中文题目:一个数组中所有数字都是成双成对出现的,只有两个数只出现一次,找出来哪两个数
先来做一题简单的:假设只有一个数,而不是两个数。
这里用到了神奇的异或。我们知道异或是具有结合律的。所以把整串数字异或下,最后就是0与所求数字的异或,也就是所求数字。
//无视我的库文件~
#include<iostream>
#include<string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
int main()
{
int a[] = { 1, 2, 33, 55, 44, 66, 9, 2, 1, 55, 44, 66, 33 };
int r=0;
for (auto i: a)
{
r ^= i;
}
cout << r;
}
下面如果是两个呢?
先全部异或一次,得到的要求的两个数的异或,取里面不同的部分,即某一位为1的那个作为区分分组。
x&-x保留最低位的1。(-x为取补码)或者x&~(n-1)效果是一样的。
代码如下:
//无视我的库文件
#include<iostream>
#include<string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <functional>
using namespace std;
void find(vector<int> a)
{
int r = 0, t = 0;
for (auto i: a)
{
r ^= i;
}
for (auto i : a)
{
if (i&r&-r)
{
t ^= i;
}
}
cout << t << " " << (t^r) << endl;
}
int main()
{
vector<int> a{ 1, 2, 33, 55, 44, 66, 9, 2, 1, 55, 44, 66, 33, 72};
find(a);
system("pause");
}
还有一种求这上面的t的方法,如下:
int t= 1;
while ((r& t) == 0)
t<<= 1;