题目:一个数组中有2个数只出现了一次,其他的数都出现了两次,写一个算法找出这两个只出现一次的数
分析:该题目可以通过异或完成,先让我举一个例子
4:0100
^5:0101
-------------
1: 0001
^5:0101
-------------
4:0100
上面的例子说明4^5^5=4;同理4^5^4=5
int find_first_1(int n)
{
int index = 1;
while( (n&1)==0)
{
n >>= 1;
index <<= 1;
}
return index;
}
这个函数的返回值index比如如果num=1100,那么index=0100=4
for(int i=0;i<len;i++)
{
if((arr[i]&index)==0)
num1^=arr[i];//其实就是分组
else
num2^=arr[i];
}
这个函数是进行分组
我打个比方: 1 1 2 2 5 3 ,那么互相异或以后的值temp=6(0110),那么返回的index=2
那么1 1 2 2 5 3 分别与2相与则为0000 ,0000,0010,0010,0000,0010,那么我们将最后一个为0的分为一组,将最后一个位为1的分为另外一组
最后为0的那组:1,1,5,
最后不为0的那组:2,2,3
然后组与组之间的元素互相以后
组0 最后异或结果为5
组1最后异或结果为3:
这样就找到了数组中这两个只出现一次的数,下面贴出代码:
// find_first_1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//寻找数组中两个单独出没的数字
int find_first_1(int n)
{
int index = 1;
while( (n&1)==0)
{
n >>= 1;
index <<= 1;
}
return index;
}
void find(int * arr, int len, int & num1, int & num2)
{
int temp = 0;
for(int i=0;i<len;i++)
temp ^= arr[i];
unsigned int index = find_first_1(temp);
num1 = 0;
num2 = 0;
for(int i=0;i<len;i++)
{
if((arr[i]&index)==0)
num1^=arr[i];//其实就是分组
else
num2^=arr[i];
}
}
int main()
{
int num1,num2;
//int arr[] = {2,2,2048,1024,4,5,4,5};
int arr[]={1 ,1, 2, 2, 5, 3 };
find(arr,8,num1,num2);
printf("%d %d\n",num1,num2);
cout<<endl;
system("pause");
return 0;
}
// find_first_1.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//寻找数组中两个单独出没的数字
int find_first_1(int n)
{
int index = 1;
while( (n&1)==0)
{
n >>= 1;
index <<= 1;
}
return index;
}
void find(int * arr, int len, int & num1, int & num2)
{
int temp = 0;
for(int i=0;i<len;i++)
temp ^= arr[i];
unsigned int index = find_first_1(temp);
num1 = 0;
num2 = 0;
for(int i=0;i<len;i++)
{
if((arr[i]&index)==0)
num1^=arr[i];//其实就是分组
else
num2^=arr[i];
}
}
int main()
{
int num1,num2;
//int arr[] = {2,2,2048,1024,4,5,4,5};
int arr[]={1 ,1, 2, 2, 5, 3 };
find(arr,8,num1,num2);
printf("%d %d\n",num1,num2);
cout<<endl;
system("pause");
return 0;
}