目录
喜欢的话还请多多支持,蟹蟹!
今天来分享一道题目,找到两只单身狗,在一组数字中找到只出现一次的两个数字,个人感觉还是挺有意思的。
题目
一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。
编写一个函数找出这两个只出现一次的数字。
例如:
有数组的元素是:1,2,3,4,5,1,2,3,4,6
只有5和6只出现1次,要找出5和6.
一、明确思路
在一堆数字中找到其中只出现一次的两个数字,这里我们就可以想到用按位异或操作符,按照按位异或操作符的原理,出现两次的的数字会在按位异或之后变成0,而0按位异或上任何数字都会得到原数字,把数组中的数字都按位异或一遍,最后会得到两个只出现一次的数字的按位异或的结果。
得出了两个数字按位异或的结果,接下来就是找出两个数字的不同,我们知道在按位异或时,两个数字的补码(数字在电脑中存储用的就是补码)同一位上的数字相同得到的结果就是1,反之就是0,我们就需要找到这个1的位置(找到其中一个就可以了),将得到的结果按位与上1,1不断地用上左移操作符,直到结果为1,,再将数组的数字根据这个位置是否为1进行分类,再次进行按位异或,得到两个单身狗数字。
二、代码实现
明确了思路之后,就可以用代码实现了,下面直接上代码加上注释。
第一步
int arr[10] = { 1,2,3,4,5,1,2,3,4,6 };
int i,count;
int sum = 0;
for (i = 0; i < 10; i++)
{
sum ^= arr[i]; //把所有数字都进行按位异或操作,得到两个单身狗数字的按位异或结果。
}
第二步
for (i = 0; i < 32; i++)
{
if (sum & 1 << i)//按位与上1,找到上一步得到的结果中数字哪个位置的数字为1
{
count = i; //记录第几位
break;
}
}
第三步
int dog1=0, dog2=0;
for (i = 0; i < 10; i++)
{
if (arr[i] & 1 << count) //将数组中这个位上不同的两种数进行分类
dog1 ^= arr[i];
else
dog2 ^= arr[i]; //分类后的数进行按位异或得到两个只出现一次数字
}
三、整体代码
#include<stdio.h>
int main()
{
int arr[10] = { 1,2,3,4,5,1,2,3,4,6 };
int i,count;
int sum = 0;
for (i = 0; i < 10; i++)
{
sum ^= arr[i];
}
for (i = 0; i < 32; i++)
{
if (sum & 1 << i)
{
count = i;
break;
}
}
int dog1=0, dog2=0;
for (i = 0; i < 10; i++)
{
if (arr[i] & 1 << count)
dog1 ^= arr[i];
else
dog2 ^= arr[i];
}
printf("两个单身狗是%d %d", dog1, dog2);
return 0;
}
结语
如果觉得写的不错,还请多多点赞、收藏,有什么不对的地方,多多指教,感谢支持。