在某些限制下从二进制序列中找到一些N的倍数

时间:2014-11-21 13:38:54

标签: python algorithm python-2.7

有人可以帮我找到解决以下编程问题的方法吗?

我目前正在使用Python 2.7

目标:我试图将一系列数字加在一起,这样当它们作为二进制数写入时,它们的总和是一系列全部1并且是某个数字N的倍数。 / p>

这是我的一般程序:

(例如) 鉴于bin(N)[2:] =' 10011' 通过适当地左移m位,我可以保证N的倍数为M ......

使得m + m0 + 0 + 0 + m0000 = M,是N的倍数。(因为N = 2 ^ 0 + 2 ^ 1 + 0 + 0 + 2 ^ 4)。

因此问题减少到找到m使得M是一系列1。

但我所有编码的尝试都是垃圾......

我不想使用%"进行猜测和检查方法。或任何分裂。理想情况下,当答案找到" 0"时,该方法会自行纠正m?在添加了所有m之后的M的二进制字符串中,但是我对其他想法开放并且效率更高的方法越好。

感谢。

1 个答案:

答案 0 :(得分:0)

理解这样的问题的最佳方法是弄清楚如何使用纸笔计算m,然后将过程机械化。

  • 鉴于输入始终是奇数(n&1==1),您知道输出是奇数(m&1==1),因为这是获得最不重要的1的唯一方法m*n)的比特列。
  • 然后您迭代执行此任务:
    • 左移输入。
    • 确定此1列中是否应该有0m
    • 您希望每列中有奇数个1 s,以将m*n的值保留为二进制1的字符串。
    • 输出1如果是奇数,0,如果偶数......
    • 不要忘记携带位: - )

以下是一个示例,将n=13(二进制1101)的位移值相加,确保底行在每列中放置1

0 0 0 0 0 0 0 0 1 1 0 1   == 1
0 0 0 0 0 0 0 1 1 0 1 0   == 1
0 0 0 0 0 0 0 0 0 0 0 0   == 0
0 0 0 0 0 1 1 0 1 0 0 0   == 1
0 0 0 0 1 1 0 1 0 0 0 0   == 1
0 0 0 1 1 0 1 0 0 0 0 0   == 1
0 0 0 0 0 0 0 0 0 0 0 0   == 0
0 0 0 0 0 0 0 0 0 0 0 0   == 0
1 1 0 1 0 0 0 0 0 0 0 0   == 1
=======================
1 1 1 1 1 1 1 1 1 1 1 1

阅读右栏(从最低位到最高位),答案为100111011,即315。所以13 * 315 == 4095,(正确地)是二进制1的字符串。

我不应该真的为你做任务但是好奇导致我用快速算法来证明这是有效的。

def number_of_ones(stack,column):
    return sum([ (value>>column)&1 for value in stack ])

def most_significant_bit(x):
    return len(bin(x))-2

def get_multiplier(n):
    assert n&1, "Must be an odd number input"
    stack = []
    column = 0
    m = 0
    carry_bit = 0
    while len(stack)==0 or column<most_significant_bit(stack[-1]):
        column_sum = number_of_ones(stack,column) + carry_bit
        if (column_sum&1)==0:
            stack.append(n<<column)
            m += (1<<column)
        # Edited to include bug fix :-)
        carry_bit = column_sum>>1
        column += 1
    return m

附录:根据您的要求,您可能希望输出为m*n

附录2:鉴于问题格式我认为这个算法总是会停止,但我还没有提出正式的证据。看到它会很有趣。