您的位置:首页 > 其它

找出一个整形数组的所有元素除了一个、两个、三个元素外,其余全是成对出现的,找出这些元素

2013-12-09 22:53 459 查看
这是常见的一种面试题,其关键思想是利用位操作的异或,同数异或为0, 而0和任何数异或都是它本身:

                0^1 = 1; 0^0 = 0; 1^1 = 0;而且满足交换律和结合律

 

对于只有一个元素不成对的值,只要将数组的每一个元素都异或操作,结果就是那个不成对的元素

int FindOne( int a[], int len)
{
int ret = -1;
int i = 0;

ret = a[0];
for(i=1; i < len; i++)
{
ret = ret ^ a[i];
}

return ret;
}


 

       对于有两个不成对的元素,则要将这两个元素分到不同的两个数组中,而且每个数组的其他元素都是成对的,则对这两个数组分别利用上面的求一个不成对的元素的方法即可。关键是怎么分组。

       对于数组a[] = {1,2,3,4,5,3,2,1} 每个元素都异或之后,结果其实就是这两个不成对的元素4和5异或的结构:4^5=1   对于结果1, 第一位是1,和5(101)一样,而4( 100 )的第一位则是0,这样就可以区分这两个元素,其他元素也按第一位是否为1分类:

1 :  000

2:010

3:011

4:100

5;101

所以1,1,2,2,4分到一组, 3,3, 5分到一组。

int FindTwo(int a[], int len)
{
int ret = -1;
int i = 0;
int j = 0;
int k = 0;
int bits = 1;
int result1 = 0;
int result2 = 0;

ret = a[0];
for(i=1; i < len; i++)
{
ret = ret ^ a[i];
}

//求取第一个为1的位
while(1)
{
if( (ret & bits) == 0)
{
bits = bits << 1;
}
else
{
break;
}
}

//将每一个元素按bits的位为1的位分类
for(i=0; i < len; i++)
{
if( (a[i] & bits) == 0)  //改位不为1
{
result1 = result1 ^ a[i];
}
else  //该位为1
{
result2 = result2 ^ a[i];
}
}

printf("result1 = %d \n", result1);
printf("result2 = %d \n", result2);

return ret;
}


这里要注意位运算符和比较运算符的优先级,( a[i] & bits ) == 0; 这里==的优先级高,在这里纠结了半天才找到,哎

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐