【发布时间】:2018-07-26 15:57:58
【问题描述】:
我需要了解为什么我的代码给出了错误的答案。任务是通过分治法创建二进制乘法。我发现了一些描述此类问题的论文: wikibooks algorithms UTSC paper (page 4)
这是我的 Python 代码 (3.5.2)
def add(A, B):
a_str = "".join([str(a) for a in A])
b_str = "".join([str(b) for b in B])
bin_a = int(a_str, 2)
bin_b = int(b_str, 2)
return [int(a) for a in str(bin(bin_a + bin_b))[2:]]
def add_n(*args):
if len(args) <= 1:
return args[0]
bin_sum = [0]
for num in args:
bin_sum = add(bin_sum, num)
return bin_sum
def shift(A, n):
if n <= 0:
return A
a_str = "".join([str(a) for a in A])
bin_a = int(a_str, 2)
bin_a = bin(bin_a << n)
return [int(a) for a in str(bin_a)[2:]]
def lfill(A, n):
return [0] * (n - len(A)) + A
def multiply(A, B):
n = len(A)
half = n // 2
if n <= 1:
return [A[0] * B[0]]
xl, xh = A[:half], A[half:]
yl, yh = B[:half], B[half:]
a = multiply(xh, yh)
b = multiply(xh, yl)
c = multiply(xl, yh)
d = multiply(xl, yl)
b = add(b, c)
a = shift(a, n)
b = shift(b, half)
return add_n(a, b, d)
有问题的测试1:
A = [1, 1, 1, 1]
B = [0, 1, 0, 0]
result: [1, 1, 1, 1, 0]
real result: [1, 1, 1, 1, 0, 0]
有问题的测试2:
A = [1, 1, 1, 1]
B = [0, 0, 0, 1]
result: [1, 1, 1, 1, 0, 0, 0]
real result: [1, 1, 1, 1]
测试 2 的值跟踪:
n half
Before Shift [2, 1]: a: [1] b:[1]
After Shift: a: [1, 0, 0] b:[1, 0]
Before Shift [2, 1]: a: [0] b:[0]
After Shift: a: [0] b:[0]
Before Shift [2, 1]: a: [1] b:[1]
After Shift: a: [1, 0, 0] b:[1, 0]
Before Shift [2, 1]: a: [0] b:[0]
After Shift: a: [0] b:[0]
Before Shift [4, 2]: a: [1, 1, 0] b:[1, 1, 0]
After Shift: a: [1, 1, 0, 0, 0, 0, 0] b:[1, 1, 0, 0, 0]
所以,正如您所见,问题在于零的计数,但因情况而异。此代码不适用于所有未配对长度的二进制文件,但这不是问题,因为它可以很容易地标准化。
【问题讨论】:
-
你做了什么来诊断问题?我没有看到任何检查哪些中间值可能不正确或跟踪执行流程的尝试。
-
添加,跟踪测试 2。实际上,因为这个算法是递归的,所以它有很多不同的值。我使用的是 Debug,但似乎问题出在算法本身。
-
因为我认为这是作业,我不会给你解决方案,但我会给你这个指针:考虑 MSB/LSB。哪些位是哪些?
-
哇,我发现了错误。谢谢。
标签: python binary multiplication divide-and-conquer