我试图找到2个给定数字之间重叠的1位数。
例如,给定5
和6
:
5 // 101
6 // 110
有1个重叠的1位(第一位)
我有以下代码
#include <iostream>
using namespace std;
int main() {
int a,b;
int count = 0;
cin >> a >> b;
while (a & b != 0) {
count++;
a >>= 1;
b >>= 1;
}
cout << count << endl;
return 0;
}
但是当我输入335
和123
时,它返回7
,但我认为这不正确
有人可以看到我的代码有问题吗?
答案 0 :(得分:2)
您现有的算法只要在剩余的位中任何位来测试匹配,就会对每个位进行计数;因为123和335有一个共同的MSB,只要这两个数字都不为零,它就是真的。 123是较小的7位,所以它确实是7次,直到该数字被完全处理。作为极端情况,128(10000000)和255(11111111)将使用您的方法返回8,即使它实际上是1。
您希望将两个数字一起开始,然后计算该结果中的1的数量
答案 1 :(得分:2)
问题是你只是打印出任何位匹配的次数,因为你为每次迭代丢掉了最低有效位(最大值是为较小的数字设置的位)。你正在比较[a] BITWISE和[b]每次迭代的所有位。你可以通过使用1:a & b & 1
进行屏蔽来纠正这个问题,这样当你每次向右移动东西时,你只是检查是否检查了最低有效位:< / p>
while (a && b){
count += a & b & 1;
a>>=1;
b>>=1;
}
答案 2 :(得分:1)
您想要计算设置的位数。相反,您的代码有点计算二进制对数。
如果最低顺序位置位,则仅递增计数。
for (int c = a & b; c != 0; c >>= 1) {
if (c & 1)
++count;
}
答案 3 :(得分:0)
略短的形式:
int countCommonBits(int a,int b) {
int n = 0;
for (unsigned v = (unsigned)(a & b); v; v >>= 1) {
n += 1 & v;
}
return n;
}
如果您知道这两个数字都是正数,则可以省略使用无符号类型。注意当使用“int”时,在负数右移的符号扩展会给你一些过度计数(即无限循环)。
很久以后...... 回顾一下旧的答案,发现了这一点。当前“接受”的答案是1)效率低下,2)如果数字是负数则是无限循环。 FWIW。