sayhitrue

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

中文题目:一个数组中所有数字都是成双成对出现的,只有两个数只出现一次,找出来哪两个数

先来做一题简单的:假设只有一个数,而不是两个数。

这里用到了神奇的异或。我们知道异或是具有结合律的。所以把整串数字异或下,最后就是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;

更多关于异或的参考这里大神的文章

更多关于Markdown相关参考这里

posted on 2016-03-29 19:38  sayhitrue  阅读(174)  评论(0)    收藏  举报