大整数乘法(递归+分治法)

目录

一、问题描述

二、思路分析

分治法介绍:

问题分析:

三、算法伪代码

四、代码实现效果

五、源代码 

六、参考文章


一、问题描述

请设计一个有效的算法,可以进行两个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




六、参考文章

分治法的经典问题——大整数相乘 - m0w3n - 博客园

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值