一、代码
#include<stdio.h>
//通过num1和num2两个参数来获取到返回结果
void FindNum(int* num, int sz, int* num1, int* num2)
{
int sum = 0;
int i = 0;
for (i = 0; i < sz; i++)
{
sum ^= num[i];//循环异或整个数组
}
//此时sum就等价于num1^num2,这个整数中一定存在某个比特位为1
int pos = 0;
for (pos = 0; pos < 32; pos++)//从sum中随便找一个比特位为1的位,寻找比特位的原理见下图
{
if ((sum&(1 << pos)) != 0)
{
break;
}
}//此时pos值对应的比特位就一定是1
for (i = 0; i < sz; i++)//按pos位是1还是0把整个数组分成两部分,分别按位异或
{
if ((num[i] & (1 << pos)) == 0)
{
*num1 ^= num[i];
}
else
{
*num2 ^= num[i];
}
}
}
int main()
{
int num[] = { 1,1,2,2,3,4,4,6 };
int sz = sizeof(num) / sizeof(num[0]);
int num1 = 0;
int num2 = 1;
FindNum(num, sz, &num1, &num2);
printf("%d ", num1);
printf("%d ", num2);
return 0;
}
二、函数原理
1、一个数组中,只有一个数字出现一次,其他出现两次,循环按位异或,最终结果一定是只出现一次的整数
a ^ b ^ b => a
现在一个数组中,两个数字出现一次,其他出现两次,核心思路还是按位异或
2、假设数组1,1,2,2,5,6,6,7,循环异或整个数组后得到结果如图
三、寻找比特位原理