乘以2个N位数,其中N是偶数。 multiply(1234,5678)返回7006652,这是正确的产品。 #multiply_opt在传递相同的参数时应该返回相同的值,但它不会。
任何想法总是非常受欢迎!
def multiply(x, y)
return x * y if x.to_s.length <= 1 && y.to_s.length <= 1
n = x.to_s.length
x_mid = x.to_s.length / 2
y_mid = y.to_s.length / 2
a = x.to_s[0..x_mid-1].to_i
b = x.to_s[x_mid..-1].to_i
c = y.to_s[0..y_mid-1].to_i
d = y.to_s[y_mid..-1].to_i
ac = multiply(a,c)
ad = multiply(a,d)
bc = multiply(b,c)
bd = multiply(b,d)
((10**n) * ac) + (10**(n/2) * (ad + bc)) + bd
end
def multiply_opt(x, y)
# Not sure if this base case is correct...
return x * y if x.to_s.length <= 1 || y.to_s.length <= 1
# Not sure exactly how to define n
n = [x.to_s.length, y.to_s.length].max
x_mid = x.to_s.length / 2
y_mid = y.to_s.length / 2
a = x.to_s[0..x_mid-1].to_i
b = x.to_s[x_mid..-1].to_i
c = y.to_s[0..y_mid-1].to_i
d = y.to_s[y_mid..-1].to_i
# Recursive Calls
s1 = multiply_opt(a,c)
s2 = multiply_opt(b,d)
s3 = multiply_opt((a + b),(b + d))
s4 = s3 - s1 - s2
(10**n)*s1 + (10**(n/2)* s4) + s2
end
答案 0 :(得分:1)
您的问题是您定义了单独的x_mid
和y_mid
,这是错误的。并且分裂必须发生在相同的地方,即n/2
,从较低的数字看。
你的例子失败的地方是第3次乘法,因为那里的操作数有2位和3位数。拆分应该分开最后一位数字。使用您的方法,3位数字被分为1和2位数,这是错误的。
更多详细信息: Karatsuba首先将您的号码拆分为
x = x1*M+x0
y = y1*M+y0
使产品
x*y = x1*y1*M^2+((x1+x0)*(y1+y0)-x1*y1-x0*y0)*M + x0*y0
可以使用较小数字的三次乘法来计算。热门使用M=B^k
,其数字基数为B
,因此x0
和y0
包含k
和{{1}的最低x
位数}}
在您的示例中,您必须决定始终使用y
或k=1
,通过Karatsuba的设计,人们会要求k=2
,这意味着x,y<M^2
。
考虑到这些想法,您的算法应该修改为
k=2
应该相应地修改第一种方法中的分裂和重建语句。