#include <iostream>
#include <sstream>
#include <cstring>
using namespace std;/函数声明//
//大整数减法;
string subBI(string A, string B);
//数字转字符串
string Int_to_String(int num);
//字符串转数字
int String_to_Int(string s);
//去掉前面的0
string remove_zero(string s);
//大整数加法
string plusBI(string A, string B);
//判断结果正负号
string judge_outcome(string A, string B);
//补齐符号
string complete_sign(string A);
////大整数加法
string plusBI(string A, string B)
{//获取字符串A、B中最长的那个字符串的长度(A、B是只是数字部分的字符串)int length = A.length() >= B.length() ? A.length() : B.length();//temp:中间运算的值,result:最后的结果string temp = "", result = "";//对齐A、Bstring part_A(length - A.length(), '0');A = part_A + A;string part_B(length - B.length(), '0');B = part_B + B;//value_A:读取的A上的每一位值;value_B:读取的B上的每一位值;count:计算是否需要借位int value_A, value_B, count = 0;//从低位开始一位一位的累减for (int i = 1; i <= length; i++){//获取四个整数当前位的值value_A = String_to_Int(A.substr(length - i, 1));value_B = String_to_Int(B.substr(length - i, 1));temp = Int_to_String(value_A + value_B);  //以字符串形式存储当前位相加的结果if (i == 1)  //最低位相加无须考虑进位{result = temp;}else if (result.length() > i - 1)  //非最低位相加需考虑已加结果是否有进位{//有进位的情况value_A = String_to_Int(result.substr(0, 1));value_B = String_to_Int(temp);temp = Int_to_String(value_A + value_B);result = temp + result.substr(1);}else  //无进位的情况{result = temp + result;}}return result;
}//大整数减法;
string subBI(string A, string B)
{//获取字符串A、B中最长的那个字符串的长度(A、B是只是数字部分的字符串)int length = A.length() >= B.length() ? A.length() : B.length();//temp:中间运算的值,result:最后的结果string temp = "", result = "";//对齐A、Bstring part_A(length - A.length(), '0');A = part_A + A;string part_B(length - B.length(), '0');B = part_B + B;//value_A:读取的A上的每一位值;value_B:读取的B上的每一位值;count:计算是否需要借位int value_A, value_B, count = 0;//从低位开始一位一位的累减for (int i = 1; i <= length; i++){//获取两个整数从尾到头的每个字符value_A = String_to_Int(A.substr(length - i, 1));value_B = String_to_Int(B.substr(length - i, 1));//两数相减,不用借位if ((value_A - count - value_B) >= 0){temp = Int_to_String(value_A - count - value_B);result = temp + result;count = 0;}//两数相减,需要借位else{//如果没到最高位,则可以一直借位if (i != length){temp = Int_to_String(value_A + 10 - count - value_B);//表示向前一位借位result = temp + result;count = 1;}//到了最高位,只能直接相减else{temp = Int_to_String(value_A - count - value_B);result = temp + result;}}}return result;
}//大整数乘法
string multiBI(string A, string B)
{//获取A、B最长字符串长度int lenA = A.length();int lenB = B.length();int length = lenA > lenB ? lenA : lenB;//补齐A、Bif (length == lenA){B = string(length - lenB, '0') + B;}else{A = string(length - lenA, '0') + A;}if (length ==1){return Int_to_String(String_to_Int(A) * String_to_Int(B));;}else{string A1, A2, B1, B2;A1 = A.substr(0, A.length() / 2 + A.length() % 2);A2 = A.substr(A.length() / 2 + A.length() % 2, A.length() / 2);B1 = B.substr(0, B.length() / 2 + B.length() % 2);B2 = B.substr(B.length() / 2 + B.length() % 2, B.length() / 2);string A1B1 = multiBI(A1, B1);string A2B2 = multiBI(A2, B2);string A1B1_plus_A2B2 = plusBI(A1B1, A2B2);string A1B2_plus_A2B1 = multiBI(plusBI(A1, A2), plusBI(B1, B2));A1B2_plus_A2B1 = subBI(A1B2_plus_A2B1, A1B1_plus_A2B2);int add_first = A.length() / 2 * 2;int add_mid = A.length() / 2;for (int i = 0; i < add_first; i++) {A1B1 = A1B1 + '0';}for (int i = 0; i < add_mid; i++) {A1B2_plus_A2B1 = A1B2_plus_A2B1 + '0';}return remove_zero(plusBI(plusBI(A1B1, A1B2_plus_A2B1), A2B2));}
}//除去前面的无效0
string remove_zero(string s)
{// 除去数字前面的零int i = 0;while (i < s.length() && s[i] == '0'){i++;}if (i < s.length()){s = s.substr(i);}else{s = "0";}return s;
}//数字转字符串
string Int_to_String(int num)
{string outcome;stringstream ss;ss << num;ss >> outcome;ss.clear();return outcome;
}//字符串转数字
int String_to_Int(string s)
{int outcome;stringstream ss;ss << s;ss >> outcome;ss.clear();return outcome;
}//判断结果正负号
string judge_outcome(string A, string B)
{//截取A、B的符号位string A_sign = A.substr(0, 1);string B_sign = B.substr(0, 1);//计数器int count = 0;if (A_sign == "-"){count++;}if (B_sign == "-"){count++;}//判断结果if (count == 1){return "-";}else{return "+";}
}//补齐符号
string complete_sign(string s)
{string temp = s.substr(0, 1);if (temp != "-"){return "+" + s;}else{return s;}
}int main()
{//A、B以字符串的形式存储大整数string A, B;//判断是否需要继续int flag = 1;while (flag){flag = 0;cout << "请输入两个乘数:" << endl;cin >> A >> B;//补全A、B的符号A = complete_sign(A);B = complete_sign(B);cout << "大整数:"<<"("<< A<<")" << " * " << "(" << B << ")" << "的结果是:" << endl;//获取结果的符号string outcome_sign = judge_outcome(A, B);//A、B减去符号A = A.substr(1);B = B.substr(1);cout<< outcome_sign + multiBI(A, B) << endl;cout << "继续计算请按1,结束按0——" << endl;;cin >> flag;}return 0;
}

与普通大整数乘法相比的改进之处:

1、原大整数乘法是根据公式进行计算的,需要进行四次乘法,其时间复杂度。而本文的公式基于Karatsuba算法,根据实际观察和验算发现可以变形为,可以观察到变形后的式子中只需要三次乘法,其时间复杂度,算法的时间复杂度得到了降低。

2、考虑到根据上述变形后的公式中三个主要的部分没有出现负数的情况,即大整数乘法的过程中主要部分都是正数,因此可以在最初输入大整数时获取大整数的符号,推断出结果的符号后,仅仅使用两个大整数的数值部分进行计算。最终输出的大整数相乘结果是一个字符串,用最先推断出的符号再连接相乘的结果,即可得到最终的真正结果。

大整数乘法(Karatsuba算法的字符串形式的C++实现)相关推荐

  1. java 整数乘法的算法,大整数乘法——分治算法的时间复杂度

    1.1原始的低效算法 我们将n位(为方便讨论简化问题,我们假设n是2的幂)十进制整数(二进制也可以)X.Y都分为2段,每段的长度是n/2位. 如果现在直接用递归或分治进行编程,其算法复杂度为: 其中: ...

  2. 大整数乘法---FFT算法

    //迭代FFT的乘法方法 // POJ 1405 Heritage /**  * input data mode:  *  the number array 1,2,3,4 use base U = ...

  3. PYTHON:大整数乘法(分治法)

    何为分治法: 分治算法的基本思想是将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同.求出子问题的解,就可得到原问题的解.即一种分目标完成程序算法,简单问题可用二分法 ...

  4. 计算机算法设计与分析 大整数乘法

    大整数乘法 问题描述 求两个不超过200位的非负整数的积. 输入形式 有两行,每行是一个不超过200位的非负整数,没有多余的前导0. 输出形式 一行,即相乘后的结果.结果里不能有多余的前导0,即如果结 ...

  5. python两数相乘代码_Python 实现大整数乘法算法的示例代码

    我们平时接触的长乘法,按位相乘,是一种时间复杂度为 O(n ^ 2) 的算法.今天,我们来介绍一种时间复杂度为 O (n ^ log 3) 的大整数乘法(log 表示以 2 为底的对数). 介绍原理 ...

  6. 分治法实验之大整数乘法(算法设计分析)

    分治法实验之大整数乘法 01. 问题描述 02. 输入格式 03. 输出格式 04. 输入样例 05. 输出样例 06. 问题分析 07. 算法设计 08. 代码实现 09. 测试结果 10. 复杂度 ...

  7. 分治算法经典问题---大整数乘法(1~32位大整数乘法)C++

    大整数乘法 大整数乘法(1~32位大整数乘法) 分治的思想 实验题目及要求(大整数乘法) 算法分析(result=m4*10^2^+(m2+m3)*10^n/2^+m1) 算法分析 代码 源文件 ma ...

  8. 【分治算法】大整数乘法

    前言 最近开了算法导论课,上来就是递归分治,大整数乘法就是分治法的典型案例,通过参考网上书上我终于编程实现了大整数乘法,特此纪念 原理 由于两个大整数直接相乘太大,所以我们可以将它划分成几个小块分别相 ...

  9. 【算法/C语言】大整数乘法(分治)

    题目: 用分治算法编程实现两个n位十进制大整数的乘法运算. 思路: 参考大整数乘法的详解 伪码: Function MulOfLargeInt(X,Y,n)** 输入:n位乘数X,Y,位数n 输出:X ...

最新文章

  1. 第6周小组作业:软件测试和评估
  2. u盘盘符不显示 win10_学会这三招,在win10上安全弹出U盘,保证数据不损坏
  3. 《移动项目实践》实验报告——Android设备操作
  4. url地址传参中文乱码处理
  5. java终结器_Java的终结器仍然存在
  6. Java 算法 开灯游戏
  7. ORACLE 多表关联 UPDATE 语句
  8. 1.2_配置Python基本环境
  9. char *p=abc与char p[]=abc的不同
  10. 全息过山车:巨蚁数字全息刺激体验
  11. 人脸对齐—3DDFA
  12. Android 分贝测试仪功能
  13. itunes备份和恢复速度一样吗_itunes如何备份短信、电话和照片及恢复教程
  14. hiho 满减优惠(暴力)
  15. 【阿里云双11薅羊毛攻略】领限量手办详细步骤
  16. mui框架scroll,鼠标滑轮可以滚动,移动端触摸无法滚动
  17. 微信开放JS SDK,再次给浏览器们上了一课
  18. 在虚拟机里虚拟打电话的代码
  19. 单片机学习笔记——微机基础知识
  20. 制作拼多多app网页css,5+App下Mui框架开发仿拼多多App

热门文章

  1. 跳跃游戏 (动态规划剪枝/前缀和/滑动窗口/BFS剪枝)
  2. 从虚拟机到容器,详谈各种服务虚拟化技术及其应用场景
  3. 【算法上车②】编译打包华为摄像头yolov3 狗识别demo
  4. 对比学习Contrastive Learning
  5. html基础之好看的header
  6. C和C++编程和学习文档
  7. html旋转线条,html5 – 为什么我在移动浏览器上看到旋转的条纹?
  8. 写论文的工具推荐(包括下载论文,写作,翻译等)
  9. TCP UDP之网络编程及数据库入门
  10. Spark数据倾斜解决方案(收藏级)