算法课设——大整数乘法

大整数乘法 ——无限大整数

    • 问题描述
    • 解法
        • 通常算法
        • 分治法
    • 分治法代码
    • 结果测试

问题描述

基于分治思想设计一个大整数乘法的实现程序,可以进行两个大整数的乘法运算,要求时间复杂度小于 O(n2)。

【输入】 分行输入两个大整数,两个整数的长度可以不相同,如果输入的不是合法的 整数,应提示重新输入。

【输出】 计算输出两个大整数的乘法结果。

解法

个人在解的时候参考了很多大神的资料,链接如下:
https://blog.csdn.net/BigData_Mining/article/details/102884892.
https://blog.csdn.net/qq_31622541/article/details/110940477
算法课设——大整数乘法_第1张图片

通常算法

算法分析

首先将X和Y分成A,B,C,D
此时将X和Y的乘积转化为图中的式子,把问题转化为求解式子的值

看起来好像有点变化,分析一下:对这个式子,我们一共要进行4次乘法(AC, AD, BC, BD),所以a=4,建立递归方程:

   T(n) = 4 * T(n / 2) + θ(n)

算法课设——大整数乘法_第2张图片

通过master定理可以求得该算法的时间复杂度为: T(n) = θ(n ^ 2),跟小学算法的时间复杂度没有区别。
具体算法如下:

算法课设——大整数乘法_第3张图片

分治法

在这里插入图片描述
对于这个公式,一共进行了三次乘法(AC,BD,(A+B)(C+D)),因此,a=3.建立递归方程:

 T(n) = 3 * T(n / 2) + θ(n),

通过master定理求得时间复杂度为:
T(n) = O(n^log2(3) = O(n^1.59 )。

具体如下:
算法课设——大整数乘法_第4张图片

分治法代码

#include
#include
#include
#include
#include
using namespace std;

class Solution {
   
public:
    /*
    这个算法主要分成几个模块来进行实现
    1. 在字符串屁股后面添加N个0
    2. 字符串相加(这里包括了对负数的操作)
    【本算法最复杂部分,因为负数操作的加入可能使得最终费用相对于原本还变高】
    3. 把字符串变成偶数串
    5. 终止条件:N=1/0的时候
    6. 字符串转数字相乘然后再转回字符串
    7. 把前面的0给去掉
    */

    string multiply(string num1, string num2) {
   
        string result = multi(num1, num2);
        result = cut_zero(result);
        return result;
    }

    string multi(string num1, string num2) {
   

        //cout<< "pre:" << num1 <<" " << num2 << endl;
        
        //下面把负号单独处理,生成新的字符串没有负号
        int final_flag = 1, flag_1 = 1, flag_2 = 1;
        if (num1[0] == '-') 
        {
   
            flag_1 = -1;
            num1 = num1.substr(1);//string substr(size_type _Off = 0,size_type _Count = npos) const;
                                  //_Off:所需的子字符串的起始位置。字符串中第一个字符的索引为 0,默认值为0。 
                                  //_Count:复制的字符数目。
                                  //返回值:一个子字符串,从其指定的位置开始。
                                  //即从1位置开始复制原字符串到目标字符串
        }
        if (num2[0] == '-')
        {
   
            flag_2 = -1;
            num2 = num2.substr(1);
        }
        // 如果异号,我们采用
        if (flag_1 + flag_2 == 0) 
        {
   
            final_flag = -1;
        }
        int maxsize = num1.size() > num2.size() ? num1.size() : num2.size();
        if (maxsize % 2 == 1) //把奇数长度的字符串改为偶数长度的,并对齐
        {
   
            maxsize += 1;
        }
        num1 = to_odd_string(num1, maxsize);//在字符串前面补零
        num2 = to_odd_string(num2, maxsize);

        //cout<< "dealed:" << num1 <<" " << num2 << endl;

        if (judge_zero(num1) || judge_zero(num2)) //判断字符串中是否含有零,因为零乘任何数都是零,所以返回零
        {
   
            return "0";
        }

        if (maxsize <= 4) //位数小于4,直接转换为int型计算
        {
   
            string res = convert_multi(num1, num2);
            if (final_flag == -1)
            {
   
                string ret = "-";
                res = ret + res;//把负号加到字符串前面
            }

          //  cout << "result:" << res << endl;
            return res; 
     

你可能感兴趣的:(算法题解,算法,c++,字符串)