您的位置:首页 > 编程语言 > C语言/C++

C语言---一组数组中只有两个数字出现一次,其他数字都是成对出现的,请找出这两个数字。

2018-02-22 00:11 776 查看
啦啦啦。。。。。。。
首先我们先找出:数组中只有一个数字出现一次,其余数字都成对出现。实现的方法其时间复杂度为O(1);使用异或:其数字的二进制位相同为0,不同为1.所有数字都异或,最后的异或结果就是那个只出现一次的数字。下面是代码实现:
void FindDifference(int arr[],int n)
{
int i = 0;
int s = arr[0];
if(n == 0 || n == 1)
{
return;
}
for(i = 1;i < n;i++)
{
s = s^arr[i];
}
if(s == 0)
{
printf("数组中所有的数字都是成对出现。\n");
}
else
{
printf("单独的数字是:%d\n",s);
}
}



如果数组中有两个数字出现一次,那么。。。。。。。我们只需要把一个数组分成两个数组,然后一个数组中有一个没有成对出现的数字,让其逐一进行异或,就可以找出只出现一次的数字。下面我们举个例子来促进理解:int[] = {1,2,3,4,1,2};整个数组异或的结果为:3(0x011)^4(0x100)=7(0x111)(若异或结果的某一位为1,就说明那两个数字的那位是不同的);对于0x111,(从低位到高位)第一位就是1.所以就可以根据整个数组的第一位是1还是0来进行分组:arr[0]  0x001;   第一组arr[1]  0x010;   第二组arr[2]  0x011;   第一组arr[3]  0x100;   第二组arr[4]  0x001;   第一组arr[5]  0x010;   第二组然后第一组和第二组分别进行异或,就可以找出不同的两个数字了。下面是具体的代码实现:
void FindTwoNumbers(int *arr,int n)
{
int i = 0;
int j = 0;
int tmp = 0;
int n1 = 0,n2 = 0;
for(j = 0;j < n;j++)
{
printf("%d ",arr[j]);
}
printf("\n");
for(i = 0;i < n;i++)
{
tmp ^= arr[i];
}
for(i = 1;i <= 32;i++)
{
if((tmp >> i) & 1 == 1)
{
break;
}
}
for(j = 0;j < n;j++)
{
if(((arr[j] >> i) & 1) == 0)
{
n1 ^= arr[j];                //在分组的同时进行异或。
}
else
{
n2 ^= arr[j];
}
}
printf("只出现一次不同的两个数字是:%d,%d",n1,n2);
}


以上都是在VS2008的环境下运行的结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐