大整数乘法

article/2025/9/14 6:42:28

设计一个有效的算法,可以计算两个n位大整数的乘法运算。

如果按照我们日常的计算方法,应该就是将两个数逐位相乘,最后加起来得到最终的结果。由于是大整数乘法,那么我们用string来存储这两个数,因为是要做乘法,我们要从两个数的最低位开始乘,并且难免会有进位,所以我们打算翻转这两个string,使得更好操作一下。

string multiply(string num1,string num2)
{int len1=num1.length(),len2=num2.length();int len=len1+len2+1;reverse(num1.begin(),num1.end());reverse(num2.begin(),num2.end());//tmp储存每次乘法的结果,res储存最后相加的结果char res[len],tmp[len];for(int i=0;i<len;i++){res[i]='0';		tmp[i]='0';}for(int i=0;i<len1;i++){//jw储存每次乘法的进位,r_jw储存最后相加的进位int jw=0,r_jw=0;for(int j=0;j<len2;j++){tmp[j]=((num1[i]-'0')*(num2[j]-'0')+jw)%10+'0';int res_temp=(res[j+i]-'0')+(tmp[j]-'0')+r_jw;res[j+i]=res_temp%10+'0'; //储存最终结果jw=((num1[i]-'0')*(num2[j]-'0')+jw)/10;r_jw=res_temp/10;}//如果最高位有进位if(r_jw!=0||jw!=0){res[len2+i]=jw+r_jw+'0';//cout<<res[len2+i]<<endl;			}}string result="";bool flag=false;for(int i=len-1;i>=0;i--){//遇到第一个正整数 if(res[i]!='0'&&!flag){result+=res[i];flag=true;}else if(flag)result+=res[i];}if(result=="") result="0";return result;
}

但是这样做算法复杂度是O(n^2)。我们想要用复杂度更低的算法来解决这个问题。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

如果采取以上算法的话时间复杂度可以降低到O(n^log2(3))。

string Add(string num1,string num2)
{reverse(num1.begin(),num1.end());reverse(num2.begin(),num2.end());string res;int len1=num1.length();int len2=num2.length();int len=min(len1,len2);int jw=0;for(int i=0;i<len;i++){int tmp=(num1[i]-'0')+(num2[i]-'0')+jw;res+=char(tmp%10+'0');//cout<<"res1:"<<res[i]<<endl;jw=tmp/10;}if(len1<len2){for(int i=len;i<len2;i++){int tmp=(num2[i]-'0')+jw;res+=char(tmp%10+'0');//cout<<"res2:"<<res<<endl;jw=tmp/10;}if(jw)res+=jw+'0';}else if(len1>len2){for(int i=len;i<len1;i++){int tmp=(num1[i]-'0')+jw;res+=char(tmp%10+'0');			//cout<<"res3:"<<res<<endl;jw=tmp/10;}if(jw)res+=jw+'0';}elseif(jw)res+=jw+'0';reverse(res.begin(),res.end());return res;
}//num1>=num2
string Sub(string num1,string num2)
{reverse(num1.begin(),num1.end());reverse(num2.begin(),num2.end());int len1=num1.length();int len2=num2.length();int len=min(len1,len2);int jw=0;string res,result;for(int i=0;i<len;i++){int a=num1[i]-'0';int b=num2[i]-'0'+jw;if(a>=b){res+=char(a-b+'0');jw=0;			}else{res+=char(a+10-b+'0');jw=1;}}for(int i=len;i<len1;i++){int a=num1[i]-'0';int b=jw;if(b==0)res+=num1[i];else if(a>=b){res+=char(a-b+'0');jw=0;}else if(a<b){res+=char(a+10-b+'0');jw=1;}}int flag=false;for(int i=res.length()-1;i>=0;i--){if(res[i]!='0'&&!flag){result+=res[i];flag=true;}else if(flag)result+=res[i];}return result;
}//两个n位大整数的乘法 
string Multiply1(string num1,string num2,int n)
{string a,b,c,d,ac,ad,bc,bd,adbc;a=num1.substr(0,n/2);b=num1.substr(n/2);c=num2.substr(0,n/2);d=num2.substr(n/2);ac=multiply(a,c);ad=multiply(a,d);bc=multiply(b,c);bd=multiply(b,d);adbc=Add(ad,bc);for(int i=0;i<b.length()*2;i++)ac+="0";for(int i=0;i<b.length();i++)adbc+="0";string res=Add(ac,Add(adbc,bd));return res;
} //两个n位大整数的乘法 
string Multiply2(string num1,string num2,int n)
{string a,b,c,d,a_b,c_d,ac,bd,a_bc_d,adbc;a=num1.substr(0,n/2);b=num1.substr(n/2);c=num2.substr(0,n/2);d=num2.substr(n/2);a_b=Add(a,b);c_d=Add(c,d);a_bc_d=multiply(a_b,c_d);ac=multiply(a,c);bd=multiply(b,d);adbc=Sub(a_bc_d,Add(ac,bd));for(int i=0;i<b.length()*2;i++)ac+="0";for(int i=0;i<b.length();i++)adbc+="0";string res=Add(ac,Add(adbc,bd));return res;
} 

http://chatgpt.dhexx.cn/article/QkUYSNeH.shtml

相关文章

大整数乘法算法

一 转换为二进制求&#xff0c;推导出的公式适合十进制计算 设X和Y都是n位的二进制整数&#xff0c;现在要计算它们的乘积XY。我们可以用小学所学的方法来设计一个计算乘积XY的算法&#xff0c;但是这样做计算步骤太多&#xff0c;显得效率较低。如果将每2个1位数的乘法或加法看…

大整数乘法的详解

一.问题 由于编程语言提供的基本数值数据类型表示的数值范围有限&#xff0c;不能满足较大规模的高精度数值计算&#xff0c;因此需要利用其他方法实现高精度数值的计算&#xff0c;于是产生了大数运算。尤其是乘法运算&#xff0c;下面就是大整数的乘法的过程&#xff08;加 …

Ubuntu server树莓派版本默认用户名密码及密码修改

树莓派安装的Ubuntu server镜像&#xff0c; 默认的初始用户及密码&#xff1a; ubuntu # user ubuntu # passwd默认信息查看 在烧入镜像的内存卡中&#xff0c; 可以查看到默认的用户信息 默认密码修改 在登录界面 输入初始化的用户名和密码后&#xff0c; 会提示是第一…

2022.04.04树莓派最新镜像问题,树莓派如何设置初始化的账户和密码

树莓派最新的arm64位系统&#xff0c;更新时间是2022年4月4日&#xff0c;这个版本的树莓派取消了默认的账户密码&#xff0c;也就是原来一直使用的pi和对应的默认密码raspberry被取消了&#xff0c;现在如果想要使用的话必须自己设置&#xff0c;下面有两种方法可以设置自己的…

树莓派启用无密码 sudo

启用无密码 sudo&#xff0c;可以在不提供密码的情况下在树莓派上运行程序。 登录 Raspberry Pi 命令行界面。假设 Raspberry Pi 的默认用户名和密码分别为 pi 和 raspberry。在命令行界面中&#xff0c;键入以下命令&#xff1a; sudo nano /etc/sudoers 3. 通过添加以下行启…

最新树莓派系统PUTTY用默认用户名和密码登录不上的解决方法

最近我在树莓派配置深度学习环境&#xff0c;然后直接载了别的博主的树莓派镜像&#xff0c;发现博主给的用户名&#xff0c;密码登不上&#xff0c;于是乎&#xff0c;就打算自己配置深度学习环境&#xff0c;结果我下在了最新版本的树莓派镜像系统&#xff08;2022-04-04-ras…

树莓派默认账号密码串口登录不了的Bug解决

一、问题总结 我用的树莓派型号是树莓派Pi3,刷机用的镜像是2023版的&#xff0c;23版的镜像文件较大8G的SD卡不够用 问题描述&#xff1a;刷完机在用串口登录树莓派的时候登录不了 &#xff01;&#xff01;&#xff01; 默认账号&#xff1a;pi 默认密码&#xff1a;raspb…

树莓派raspberry pi 4 SSH默认密码无法登录解决办法

以前玩过一段时间树莓派&#xff0c;只要开通ssh就可以&#xff0c;默认用户pi,默认密码: raspberry。 远程连接就可以。 但今天再玩却死活无法登录&#xff0c;如下&#xff1a; 出了什么幺蛾子哦&#xff1f;&#xff01;&#xff01; 上网一查&#xff0c;才知道pi账号在…

【入坑树莓派】烧录系统都烧录了三次(树莓派默认账户密码错误/已删除)

为什么会烧录了三次&#xff1f;我因为实在不知道问题出在哪&#xff0c;所以只能推倒重来三次。。。 三次&#xff0c;两次连接不上WiFi&#xff0c;好不容易一次连接上了&#xff0c;出现了下面这幅画面 再三确认了默认用户名是pi&#xff0c;密码raspberry&#xff0c;奈何…

树莓派用默认账号和密码登录不上怎么办;修改树莓派的密码

目录 一、重置树莓派的默认账号和密码 二、修改树莓派的密码 三、超级用户和普通用户的切换 一、重置树莓派的默认账号和密码 在SD卡中根目录建立文件userconf 在userconf中输入如下内容&#xff1a; pi:$6$/4.VdYgDm7RJ0qM1$FwXCeQgDKkqrOU3RIRuDSKpauAbBvP11msq9X58c8Q…

树莓派默认密码_树莓派介绍:没有显示器,怎样远程控制树莓派?

树莓派(Raspberry Pi)是学习计算机知识、架设服务器的好工具&#xff0c;价格低廉&#xff0c;可玩性高。 由于树莓派系统开始时默认是不开启ssh连接的&#xff0c;没有开启ssh就无法连接电脑&#xff0c;后续的操作也就无从谈起。 准备工作 1.烧录好系统的树莓派3B主板 2.普…

树莓派默认密码_树莓派快速指南,从购买到开机

本文给树莓派初学者&#xff0c;或者准备入手树莓派的同学看&#xff0c;主要包括什么是树莓派&#xff0c;入门树莓派需要那些配件&#xff0c;如何烧录树莓派系统&#xff0c;和树莓派的开机指南。如果你不知道学习树莓派需要那些配件&#xff0c;或者购买了树莓派不知道怎么…

树莓派的登录

一、串口登录&#xff1a; 由于树莓派在默认情况下&#xff0c;树莓派的串口和蓝牙链接。而我们要进行串口登录就得断开蓝牙&#xff0c;把串口用来进行数据通信。 1.打开SD卡根目录的"config.txt"文件&#xff0c;将以下内容添加在最后并且保存。 dtoverlaypi3-m…

树梅派raspberrypi的su密码root密码是什么

入手了树梅派4B,上电后&#xff0c;安装portainer的时候想获得root权限&#xff0c;输入su&#xff0c;恩&#xff1f;密码是多少&#xff1f;不记得了&#xff0c;输了好几遍登录密码也不对&#xff0c;无法进入了。 查了一下&#xff0c;原来树莓派的Raspbian系统root用户默…

【mysql】mysql 模糊查询 like 语句

mysql 模糊查询 like 语句 一 like 语句 %xxx%&#xff1a;查询 username 字段中包含 xxx 的记录。 select * from user where username like ‘%xxx%’; %xxx&#xff1a;查询 username 字段中以 xxx 结尾的记录。 select * from user where username like ‘%xxx’; xx…

mybatis模糊查询like语句怎么写

写法为&#xff1a;1、使用“${...}”&#xff0c;语法为“like ${...}”&#xff1b;2、使用“#{...}”&#xff0c;语法为“like #{...}”&#xff1b;3、使用CONCAT函数连接参数形式&#xff0c;语法为“like CONCAT(%,#{...},%)”。 本教程操作环境&#xff1a;windows7系统…

mysql like模糊查询表名_mysql模糊查询like/REGEXP

增删改查是mysql最基本的功能&#xff0c;而其中查是最频繁的操作&#xff0c;模糊查找是查询中非常常见的操作&#xff0c;于是模糊查找成了必修课。 like模式 like意思是长得像&#xff0c;有两个模式&#xff1a;_和% _表示单个字符&#xff0c;通常用来查询定长的数据&…

模糊查询like用法实例(Bee)

like通过两个匹配符%和_进行模糊查询. %: 匹配任意个任意字符 _: 匹配一个字符 以下以userid为例, 在数据库中的值如下图所示: V1.11及之前版本&#xff0c; 使用Op.like&#xff0c; 需要判断值是否为空字段&#xff0c;是否只含有匹配符(%和_) Op.like可以创建比左右匹配…

sql模糊查询 like

like 经常与where 字句和通配符在一块进行使用&#xff0c;表示像啥啥&#xff0c;模糊查询 通配符 主要是 _ 和 %   &#xff05; 百分号表示零个&#xff0c;一个或多个字符   _ 下划线表示单个字符 **注意&#xff1a;**1、 MS Access使用问号&#xff08;?&#xff09…

SQL中的模糊查询like

首先我们创建一个Person表。 create table Person(cname varchar2(50),cage number(3) );插入一些数据: insert into Person (cname,cage) values(张三,19); insert into Person (cname,cage) values(张三丰,20); insert into Person (cname,cage) values(张一,30); insert i…