相似的算法实现产生不同的结果
Similar algorithm implementation producing different results
我正在尝试了解 Karatsuba 乘法算法。我写了以下代码:
def karatsuba_multiply(x, y):
# split x and y
len_x = len(str(x))
len_y = len(str(y))
if len_x == 1 or len_y == 1:
return x*y
n = max(len_x, len_y)
n_half = 10**(n // 2)
a = x // n_half
b = x % n_half
c = y // n_half
d = y % n_half
ac = karatsuba_multiply(a, c)
bd = karatsuba_multiply(b, d)
ad_plus_bc = karatsuba_multiply((a+b), (c+d)) - ac - bd
return (10**n * ac) + (n_half * ad_plus_bc) + bd
这个测试用例不工作:
print(karatsuba_multiply(1234, 5678)) ## returns 11686652, should be 7006652
但是如果我使用 this answer 中的以下代码,测试用例会生成正确的答案:
def karat(x,y):
if len(str(x)) == 1 or len(str(y)) == 1:
return x*y
else:
m = max(len(str(x)),len(str(y)))
m2 = m // 2
a = x // 10**(m2)
b = x % 10**(m2)
c = y // 10**(m2)
d = y % 10**(m2)
z0 = karat(b,d)
z1 = karat((a+b),(c+d))
z2 = karat(a,c)
return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0)
这两个函数看起来像是在做同样的事情。为什么我的不起作用?
似乎在 kerat_multiply
实施中,您无法为最后一个 return 使用正确的公式。
在最初的 kerat
实现中,值 m2 = m // 2
在最后一个 return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0)
(2*m2)
所以我认为您需要添加一个新变量,如下所示 n2 == n // 2
以便您可以在最后一个 return 中将其乘以 2,或者使用原始实现。
希望对您有所帮助:)
编辑:这是因为 2 * n // 2
不同于 2 * (n // 2)
n = max(len_x, len_y)
n_half = 10**(n // 2)
n2 = n // 2
a = x // n_half
b = x % n_half
c = y // n_half
d = y % n_half
ac = karatsuba_multiply(a, c)
bd = karatsuba_multiply(b, d)
ad_plus_bc = karatsuba_multiply((a + b), (c + d)) - ac - bd
return (10**(2 * n2) * ac) + (n_half * (ad_plus_bc)) + bd
我正在尝试了解 Karatsuba 乘法算法。我写了以下代码:
def karatsuba_multiply(x, y):
# split x and y
len_x = len(str(x))
len_y = len(str(y))
if len_x == 1 or len_y == 1:
return x*y
n = max(len_x, len_y)
n_half = 10**(n // 2)
a = x // n_half
b = x % n_half
c = y // n_half
d = y % n_half
ac = karatsuba_multiply(a, c)
bd = karatsuba_multiply(b, d)
ad_plus_bc = karatsuba_multiply((a+b), (c+d)) - ac - bd
return (10**n * ac) + (n_half * ad_plus_bc) + bd
这个测试用例不工作:
print(karatsuba_multiply(1234, 5678)) ## returns 11686652, should be 7006652
但是如果我使用 this answer 中的以下代码,测试用例会生成正确的答案:
def karat(x,y):
if len(str(x)) == 1 or len(str(y)) == 1:
return x*y
else:
m = max(len(str(x)),len(str(y)))
m2 = m // 2
a = x // 10**(m2)
b = x % 10**(m2)
c = y // 10**(m2)
d = y % 10**(m2)
z0 = karat(b,d)
z1 = karat((a+b),(c+d))
z2 = karat(a,c)
return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0)
这两个函数看起来像是在做同样的事情。为什么我的不起作用?
似乎在 kerat_multiply
实施中,您无法为最后一个 return 使用正确的公式。
在最初的 kerat
实现中,值 m2 = m // 2
在最后一个 return (z2 * 10**(2*m2)) + ((z1 - z2 - z0) * 10**(m2)) + (z0)
(2*m2)
所以我认为您需要添加一个新变量,如下所示 n2 == n // 2
以便您可以在最后一个 return 中将其乘以 2,或者使用原始实现。
希望对您有所帮助:)
编辑:这是因为 2 * n // 2
不同于 2 * (n // 2)
n = max(len_x, len_y)
n_half = 10**(n // 2)
n2 = n // 2
a = x // n_half
b = x % n_half
c = y // n_half
d = y % n_half
ac = karatsuba_multiply(a, c)
bd = karatsuba_multiply(b, d)
ad_plus_bc = karatsuba_multiply((a + b), (c + d)) - ac - bd
return (10**(2 * n2) * ac) + (n_half * (ad_plus_bc)) + bd