首页 > 其他 > 详细

寻找一组整数中出现了奇数次的数

时间:2020-07-30 21:31:20      阅读:96      评论:0      收藏:0      [点我收藏+]

大致问题描述:

问题1:给一组整数,里面有且只有1个数出现了奇数次,请找出这个数?

问题2:给一组整数,里面有且只有2个数出现了奇数次,请找出这两个数?

 

思路引导:

此处需要用到布尔运算中的“异或”。a与b进行异或运算(a^b),是当a与b不相同时为真。即a=0,b=1或a=1,b=0时为真。

可推导及验证:a^a = 0,a^0 = a => a^b^a = b^a^a = b^0 = b, 

 

解答1:

将该组数依次进行“异或运算”,得出的值即为出现了奇数次的1个数。

假设:intList={a,b,c,...,c,b,a,t} ,那么 a^b^c^...^c^b^a^t = t^a^a^b^b^c^c... = t ^ = t 即可找出出现了奇数次的唯一一个数t

简单示例代码:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     int intList[7] = {10, 3, 15, 4, 15, 4, 10};
 8     int t = 0;
 9     for (int i = 0; i < 7; ++i)
10     {
11         t = t ^ intList[i];
12     }
13     cout << t << endl;
14     return 0;
15 }

 

解答2:

既然出现在了一起,那么肯定也是要用到“异或”操作的啦。

将该组数依次进行“异或运算”,根据上述的推导也不难看出,最后的结果为出现了奇数次的两个数的异或值a^b。

现在关键需要的是怎么才能将a和b从a^b中分离出来。直接给思路好了,我是不知道怎么推出来。

a与b既然不相同,那么他们的对应二进制位中肯定不相等的,那么我们找出一个不相等的那一位,将这组数中所有的数分成a阵营,b阵营,再对着两个阵营进行组内的“异或”运算,就变成了问题1了。

 1 #include <iostream>
 2 #include <cmath>
 3 
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int intList[8] = {10, 3, 15, 4, 15, 4, 10, 8};
 9     int t = 0;
10     for (int i = 0; i < 8; ++i)
11     {
12         t = t ^ intList[i];
13     }
14 
15     int k = 0;
16     for (int i = 1; i < 8; ++i)
17     {
18         if (t % (int)pow(2, i) != 0)
19         {
20             k = i;
21             break;
22         }
23     }
24 
25     int a = 0, b = 0;
26     int mi = (int)pow(2, k - 1);
27 
28     for (int i = 0; i < 8; ++i)
29     {
30         if ((intList[i] & mi) == 0)
31         {
32             a ^= intList[i];
33         }
34         else
35         {
36             b ^= intList[i];
37         }
38     }
39 
40     cout << a <<   << b << endl;
41 
42     return 0;
43 }

 

寻找一组整数中出现了奇数次的数

原文:https://www.cnblogs.com/lxnow/p/13405650.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!