|
- //一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字(使用位运算)
- int arr[] = { 1,2,3,4,5,6,7,8,9,10,10,8,7,9,5,3,2,1 };
- int len = sizeof(arr) / sizeof(arr[0]);
- int ret = 0;
- for (int i = 0; i < len; ++i)
- // 最后得出ret是这两个数字异或的结果
- ret ^= arr[i];
- // 找到二进制中一的位置
- int pos;
- for (int i = 0; i < 8 * sizeof(int); ++i) {
- if (((ret >> i) & 0x1) == 1) {
- pos = i;
- break;
- }
- }
- // 根据这个位置,将数分为两组
- int x = 0;
- int y = 0;
- for (int i = 0; i < len; ++i) {
- printf("%d\n", arr[i] >> pos);
- if (((arr[i] >> pos) & 0x1) == 1)
- x ^= arr[i];
- else
- y ^= arr[i];
- }
- printf("%d,%d\n", x, y);
复制代码
就是根据那个pos吧数组分成两个数组没看懂,希望那位大佬能给解答下
假设只出现一次的两个数分别是x和y
1. 整体异或一遍 结果是x^y;
2.把x,y分开 :
因为 x!= y , 令 z = x^y ,z !=0
z是int型, 一共有8*sizeof(int) 位 ,这么多位一定至少有一位是不同的,(代码里是从低位开始找,找到第一个1)
只要找到这个1 ,x和 y就区分出来了
假设这个1在第i位,那么x的第i位和y的第i位一定是不同的(因为异或等于一)
这样通过判断这一位,分为两组,除了x和y其他数都是成对出现的,所以 结果就出来了。
|
上一篇: 为什么Unicode的情况下无法输出汉字呢?下一篇: 麻烦帮忙讲解下,各位大佬,感谢
|