目录
一、问题描述
请设计一个有效的算法,可以进行两个n位大整数的乘法。(n=2^k, k=1,2,3....)
二、思路分析
分治法介绍:
分治法: 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。即一种分目标完成程序算法,简单问题可用二分法完成。
有两点需要记住:
(1) 分治法基本思想是将一个规模为n的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同。
(2)递归的解这些子问题,然后将各子问题的解合并得到原问题的解。
分治法的重点是分析问题是否可以划分为规模较小的子问题,难点是如何划分以及划分之后如何将各个子问题的解合并成最终的解。这一般需要用到数学知识或者其他理论。
问题分析:
我们可以把X分成a b两部分, Y分成c d两部分
那么就有如下操作
我们考虑到这里有4个乘法ac ad bc bd,我们是不是可以通过减少乘法的次数来降低时间复杂度呢?答案是可以的,进行如下操作:
这两个算法的时间复杂度
但是要注意a+b, d+c可能得到m+1位的结果,使问题规模扩大,所以我们选择这里面的第一种算法 。
三、算法伪代码
四、代码实现效果
五、源代码
# 理想状态下大整数乘法
# X = a b
# Y = c d
# XY = ac10^n + (ad+bc)10^(n/2) + bd O(n^2)
# XY = ac10^n(移位操作) + [(a-b)(d-c)+ ac + bd]10^(n/2) + bd O(n^1.59)
def SING(N):
return 1 if N > 0 else -1
def BigNumerMultiply(X, Y, n):
sign = SING(X) * SING(Y)
X = abs(X)
Y = abs(Y)
# 递归退出条件
if X == 0 or Y == 0:
return 0
elif n == 1:
return sign * X * Y
else:
halfN = int(n / 2) # 也可以使用字符串切割获取
a = int(X / pow(10, halfN))
b = int(X % pow(10, halfN))
c = int(Y / pow(10, halfN))
d = int(Y % pow(10, halfN))
AC = BigNumerMultiply(a, c, halfN)
BD = BigNumerMultiply(b, d, halfN)
ABCD = BigNumerMultiply(a-b, d-c, halfN)
result = AC*pow(10, n)+(ABCD+AC+BD)*pow(10, halfN)+BD
return sign * result
if __name__ == '__main__':
print('理想状态下用法!')
X = int(input('请输入第一个n(n=2^k)位整数:'))
Y = int(input('请输入第二个n(n=2^k)位整数:'))
n = len(str(X))
result = BigNumerMultiply(X, Y, n)
print('分治乘法:{}'.format(result))
print('普通乘法:{}'.format(str(X * Y)))
# 样例输入:
# 1. 2.
# 4567 12345678
# 1234 12345678
#
#
# 错误输入:
# 1. 2.
# 123456 123
# 123456 123