最近在学习Coursera上Stanford的algorithm课程,第一周是有关Karatsuba算法的,因而编写了一段python代码。需要说明和感谢的是https://blog.csdn.net/popoffpopoff/article/details/81903768
这位博主,我借鉴了他所写的代码的大部分,然而发现一个小问题,并进行了修正。
另外,所写的代码仍然是很局限的,仅限于2的整数次幂输入,限于目前水平,不想花过多时间进行研究,希望能有后人将这个继续研究下去。
# 这是我自己写的karatsuba算法,但是仍然有缺陷,比如万一是9位数,怎么办?但是现在网课赶进度,就没有细究了
def karatsuba(x,y):
if len(str(x)) == 1 or len(str(y)) == 1:
return x*y
if len(str(x)) != len(str(y)):
return x*y # 事实证明这一句非常重要,即使原始输入是2的整数次幂,在计算过程中也可能出现123*21这一类非整的情况。不加这一句
# 就会错。
n = max(len(str(x)), len(str(y)))
print("n", n)
half = n//2
print("half", half)
x1 = x // 10 ** half # 十位数
print("x1", x1)
x0 = x % 10 ** half # 个位数
print("x0", x0)
y1 = y // 10 ** half # 十位数
print("y1", y1)
y0 = y % 10 ** half # 个位数
print("y0", y0)
z0 = karatsuba(x0, y0)
print("z0", z0)
z2 = karatsuba(x1, y1)
print("z2", z2)
z1 = karatsuba((x0+x1), (y0+y1)) - z0 - z2
print("z1", z1)
z = z2 * 10 ** n + z1 * 10 ** half + z0
print("z", z)
return z
c = karatsuba(12345678, 87654321)
print(c)
另外,在维基百科上竟然搜到了python代码实现,我相信肯定比我的更好,但是我也没花时间仔细研究了,因为看起来好像有点复杂,我也将代码贴上:
def karatsuba(num1, num2):
num1Str, num2Str = str(num1), str(num2)
if num1Str[0] == '-': return -karatsuba(-num1, num2)
if num2Str[0] == '-': return -karatsuba(num1, -num2) # 显然是来判断正负的,不过我很好奇为什么是两个负号,那岂不就白费了吗?
if num1 < 10 or num2 < 10: return num1 * num2
maxLength = max(len(num1Str), len(num2Str))
num1Str = ''.join(list('0' * maxLength)[:-len(num1Str)] + list(num1Str))
# Python join() 方法用于将序列中的元素以指定的字符连接生成一个新的字符串。
num2Str = ''.join(list('0' * maxLength)[:-len(num2Str)] + list(num2Str))
splitPosition = maxLength // 2
high1, low1 = int(num1Str[:-splitPosition]), int(num1Str[-splitPosition:])
high2, low2 = int(num2Str[:-splitPosition]), int(num2Str[-splitPosition:])
z0, z2 = karatsuba(low1, low2), karatsuba(high1, high2)
z1 = karatsuba((low1 + high1), (low2 + high2))
return z2 * 10 ** (2 * splitPosition) + (z1 - z2 - z0) * 10 ** splitPosition + z0
c = karatsuba(12345678, 87654321)
print(c)