确定一个数字的总和是否包含给定的2的幂

时间:2017-09-05 22:45:02

标签: algorithm performance math

标题非常糟糕,但我想不出如何总结这个问题。

基本上,每个数字都可以通过添加两个幂来形成,每个数字最多出现一次。例如20 = 16 + 4,27 = 16 + 8 + 2 + 1等

确定给定数字是否出现在另一个数字的分解中的最有效方法是什么?

简单地计算要添加的全部数字并不难,并查看数字是否出现在那里。但必须有某种捷径,对吧?当我只需要验证给定数字的存在时,计算整个集合似乎有点过分了。

3 个答案:

答案 0 :(得分:3)

您正在询问如何检查是否设置了特定位。

问题“数字2 ** x是否出现在y的分解中?”相当于问题“在y的二进制表示中是否设置了位x?”。

所以你可以使用按位运算符来检查 - 伪代码:

bit_is_set = (y & 2**x != 0)

答案 1 :(得分:1)

  • 获取数字的二进制表示。
  • 查看代表你正在寻找的2的力量的位是否已设定。

示例:

要查找256(= 100000000 2 )是否由4(= 100 2 )组成,请参阅3 rd 位设置或不设置256的二进制表示。在这种情况下,它没有设置。

另外,看到260(= 10000100 2 )确实由4组成,因为它的第3位已设置。

答案 2 :(得分:1)

形成数字的2的权力列表:

[2 ** (31 - i) for i, j in enumerate('{0:032b}'.format(x)) if j == '1']

然后您可以使用in进行会员资格测试。

>>> x
27
>>> [2 ** (31 - i) for i, j in enumerate('{0:032b}'.format(x)) if j == '1']
[16, 8, 2, 1]
>>> 4 in [2 ** (31 - i) for i, j in enumerate('{0:032b}'.format(x)) if j == '1']
False

其中

  • '{0:032b}'.format(x)将数字格式化为32位二进制字符串。

  • enumerate('{0:032b}'.format(x))用于为每个位分配索引。

  • 然后我们查找1(j == '1')的位,并提取2 2 ** (31 - i)的相应幂。