一般情况下,我们发现两个数字之间的共同因素,即8和12为4。 但是在编程语言中,当两个数字除以2时,我想找到公共数字。 我们将两个数字除以2并检查公共数字 喜欢数字8和11 8-将4-→2 11-将5-→2 她的公共号码是2。 我想有效地实现它高达10 ^ 9的数字。 她是我的实施
long long i,j;
while(i!=1||j!=1)
{
i=i/2;
j=j/2;
if(i==j)
flag=1;
break;
}
但是我和j在不同的时间会相同。如何实现呢?
答案 0 :(得分:4)
你可以用更复杂的逻辑来做到这一点 - 使用两个数字并且总是将它们中的较大数字分开:
int get(int a, int b) {
while (a != b) {
if (a < b) {
swap(a, b);
}
a /= 2;
}
return a;
}
说明:当除以2时,任何正整数最终会变为1,因此周期将终止,当a
和b
都为1时,这将发生在最坏的情况。每一步我确保a不小于b然后我除以2.
答案 1 :(得分:2)
我希望在两个数字除以2时找到公共数字
你的问题有点模糊。我假设你想要找到2的最大公共分割能力?
由于它们的尾随零,可以很容易地以二进制检测到2的幂:
1 00000001
2 00000010
4 00000100
8 00001000
16 00010000
32 00100000
64 01000000
128 10000000
所有在其素数因子分解中具有单个2的数字只有一个尾随零:
2 00000010 2
6 00000110 2*3
10 00001010 2*5
14 00001110 2*7
18 00010010 2*3*3
您可以对4,8,16等的倍数执行相同的操作,并且可以得出结论:您可以通过其二进制表示中的尾随零的数量来检测数字中2的幂。
2的倍数(不是4的倍数)将以10结尾,4的倍数(不是8的倍数)将以100结尾,依此类推。在最右边的1之前的位对我们来说并不感兴趣。
所以我们想做的就是隔离最右边的1位。幸运的是,有一个很好的技巧:
int rightmost_bit(int x)
{
return x & -x;
}
这是如何工作的?如果你看两个补码中的x
和-x
的二进制表示,它们只共享一个1位,即最右边的,这正是我们感兴趣的那个:
*
40 00101000
-40 11011000
& *
8 00001000
x
最右边的位右侧的所有位在-x
中也为0,而-x
左侧的所有位都与x
中的位相反因此,当它们与binary-and。
找到最大公共分割能力2的天真方法是:
int gcd_p2_naive(int a, int b)
{
return std::min(rightmost_bit(a), rightmost_bit(b));
}
但是我们可以用另一个简单的技巧做得更好,我刚想出来的那个:
int gcd_p2(int a, int b)
{
return rightmost_bit(a | b);
}
为什么这样做?我会将这种开放作为读者的练习;)