一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。
思路:一个数组中只出现一次,考虑位运算符:抑或;抑或的结果为,相同位为0,不同位为1.所以如果两个数相等时那么抑或结果为0,且0与任何一个数抑或的结果都为原数。故当数组中只有一个数出现一次时,可以从头到尾抑或数组的每一个元素,最后的结果一定是唯一的数。
当数组中有两个数只出现一次时,按照上述办法抑或的结果为这两个是数抑或的结果。可以想办法把数组根据这个抑或结果分为两个数组,每个数组中只有一个数出现一次。考虑:当这两个数抑或的结果中肯定至少有一位为1,而为1 的这一位在这两个数中肯定不相等(也就是一个数的这位为0一个为1).根据第一次出现1的位置把数组划分为两组,假设第一个1出现的位置为第N位,那么把原数组中此位为1的放在一个数组,剩下的放在两外一个数组。然后对这两个数组按照一个数组中只有一个数字出现一次的方法处理。
void FindtheNum(vector<int >data,int *num1,int *num2)//num1,num2为只出现一次的数
{
int size=data.size();
if(size<2)
std::cout<<"error!"<<std::endl;
int result=0;
for(int i=0;i<size;i++)
result=result^data[i];
unsigned int indexof1=indexOfFirst1(result);//获得第一次出现1的位置
for(int i=0;i<size;i++)
{
*num1=*num2=0;
if(IsBit1(data[i], indexof1))//IsBit1()为判断当前数字的 indexOfFirst1位是不是1
*num1=*num1^data[i];
else
*num2^=data[i];
}
//求出的num1,num2为所求数字
}
unsigned int indexOfFirst1(int result)//求result中第一次出现1的位置(由低到高)
{
int index=0;
while((result&1)==0&&(index<8*sizeof(int)))//(index<8*sizeof(int))判断位数不超过32为
{
result=result>>1;
++index;
}
return index;
}
bool IsBit1(int data,unsigned int index)//判断data的第index位是否为1
{
data=data>>index;
return (data&1);
}