#include<iostream>
using namespace std;
int GetLength(int *arr)
{
return (sizeof(arr) / sizeof(arr[0]));
}
void Swap(int *arr, int i, int j)
{
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
//获取数组中唯二奇数次出现的元素
int GetOddTimesNum2(int *arr)
{
int err = 0, erranother = 0;
for (int i = 0; i < GetLength(arr); i++)
{
err ^= arr[i];
/*
假设要找到的两个数字为A和B
err = A^B
*/
}
int errRightOne = err & (~err + 1);
/*
获取err(A^B)的二进制格式的最右侧的一个一
由于err = A^B
value(dir(errRightOne)) = 1
证明 在该位置上, A与B的状态不同,由此将arr数组区分为两部分
一部分为该位置上是0的数字
一部分为该位置上是1的数字
A与B必定分别在两部分中
假设在A部分中
将errRightOne与其它所有的数字亦或会得到这样的结果
或者 其它数字在errRightOne位置之前的数字与errRightOne一样
或者 其它数字在errRightOne位置之前的数字与errRightOne不一样
如果不一样,那么两两亦或得到0
如果一样那么与erranother亦或
这个时候得到的数字再与B中满足条件的亦或就能得到A或者B
假定为A
B = A^B^A
代码如下:
*/
for (int i = 0; i < GetLength(arr); i++)
{
if (arr[i] & errRightOne != 0)
erranother ^= arr[i];
}
err ^= erranother;
return (err, erranother);
}