首页 > 编程知识 正文

leetcode四数相加II(LeetCode大数运算)

时间:2023-05-03 19:02:14 阅读:123265 作者:3713

415 .字符串加法题意:计算两个指定字符串格式的非负整数num1和num2,并计算它们的和。

返回值:返回相加结果字符串。

说明:

1、num1和num2长度均小于51002,num1和num2只包含0-93、num1和num2 都不包含任何前导零4的数字,内置的BigInteger

看看加法的情况吧。

步骤 1、按从低到高的顺序逐位添加,包括进位数字。

2、判断目前加在一起的数是否超过10,超过10时提前,从现在数中减去10。

3、重复步骤1和步骤2,直到遍历字符串。

4、最后检查有无进位,有进位的话加上进位,最终得到的是我们的结果。

提示: 1、因为不知道最终结果的长度,所以将得到的各位的结果依次添加到结果字符串中。 因此,这道题主要考察对字符串的模拟,模拟两个整数相加的情况。,最终需要反转结果字符串。

2、处理各字符串时,从最高位开始处理。 最高位对应于数字中的最低位。

c代码class solution { public : stringaddstrings (string num 1,string num2) { string res; //结果字符串intI=num1.size(-1,j=num2.size )-1,carry=0; //从顶层开始字符串while(I=0||j=0) ) if ) I=0) carry=) num1[I]-'0' ); //检查每个字符串是否已处理完if(j=0) carry=) num2[j]-'0' ); res.push_back () Carrie ) '0); //本位应该是多少carry/=10; //计算的进位I----,j----; }if(carray ) RES.push_back ) carray'0); //最后检查是否有进位reverse(RES.begin,res.end ) ); //得到的结果相反,所以反转字符串,作为最终结果的返回RES; }; 解决了这个问题,可以解决以下几个问题。

得到的结果是反的

1、LeetCode 445. 两数相加 II

给出高精度减法2、LeetCode 66. 加一个正整数,计算它们的差,计算结果可能为负数。

题意:两行,每行包含整数。

输入格式:共一行,包括要求的差。

输出格式:1整数长度10^5

数据范围:

32

11

输入样例:

21

构想:输出样例:

看看减法的情况吧。 (类似于加法)

(1、位数的各位减去小数的各位,每位从下位到上位依次减去。 包括借位。

2、判断当前位数的减法是否小于0。 如果小于0,则提前一位租用,然后将当前数量加10,租用的位置为1。 否则,借用位置等于0。 然后计算当前数量的结果,并存储在结果字符串中。

3、重复步骤1和步骤2,直到遍历字符串。

4、检查最后一个字符串中是否包含开头的0。 如果缺少前0,则结果字符串最后翻转。

提示: 1、因为不知道最终结果的长度,所以将得到的各位的结果依次添加到结果字符串中。 因此,这道题主要考察对字符串的模拟,模拟两个整数相减的情况。,最终需要反转结果字符串。 可以将输入的两个整数中的每一个位放入容器中进行处理。

2、处理各字符串时,从最高位开始处理。 最高位对应于数字中的最低位。

c代码# include iostream # includevectorusingnamespacestd; //returna=bboolcmp (矢量inta,矢量intb ) {

if(A.size()!=B.size()) return A.size()>B.size(); for(int i=A.size()-1;i>=0;i--){ if(A[i]!=B[i]) return A[i]>B[i]; } return true;}vector<int> sub(vector<int>&A,vector<int>&B){ vector<int> res; int temp=0; for(int i=0;i<A.size();i++){ temp=A[i]-temp; if(i<B.size()) temp-=B[i]; res.push_back((temp+10)%10);//当temp>0时,(temp+10)%10=temp。当temp<0,则(temp+10)为当前值,所以将两种情况合并了。 if(temp<0) temp=1;//当temp<0表示借位。 else temp=0; } while(res.size()>1&&res.back()==0) res.pop_back();//当情况为:999-999=000,所以去掉前导0 return res; }int main(){ string a,b; cin>>a>>b; vector<int> A,B; for(int i=a.size()-1;i>=0;i--) A.push_back(a[i]-'0'); for(int i=b.size()-1;i>=0;i--) B.push_back(b[i]-'0'); if(cmp(A,B)){ vector<int> res=sub(A,B); for(int i=res.size()-1;i>=0;i--) printf("%d",res[i]); //反向输出,则为结果 }else{ vector<int> res=sub(B,A); cout<<'-'; for(int i=res.size()-1;i>=0;i--) printf("%d",res[i]); } return 0;}

解决了这道题,可以去解决 MiOJ 3. 大数相减(字符串减法)

43. 字符串相乘

题意:给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

返回值:返回相乘后的结果字符串。

说明:

1、num1 和num2 的长度都小于 1102、num1 和num2 都只包含数字 0-93、num1 和num2 均不以0开头,除非是0本身4、你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式

前言:

对于比较小的数字,我们可以直接将两个数字相乘得到结果。但是本道题的两个字符串的长度小于110,说明有可能达到100以上。所以直接用两数相乘,乘数都有可能无法保存,更不用说要保存结果了。那么我们只能手动模拟字符串相乘,请看以下模拟的情况:

对于手动模拟的思路是,先算789 * 2,再算789 * 50,对于789 * 50直接相当于789 * 5往后错一位。对于这个过程我们设计了乘法进位,和加法进位。对于三位数乘三位数,有三位数的取值范围为:[100,1000),所以三位数乘三位数的取值范围为:[10000,1000000)。有可能是五位数,有可能是六位数。我们要找到一套简单一致的规则来让计算机计算。我们看789 * 2,实质是:2 * 9 + 80 * 2 + 700 * 2,789 * 50,实质是:50 * 9 + 80 * 9 + 700 * 9 。看以下根据本质计算的结果:

我们通过计算每个数字的每一位和另一个数字的每一位相乘,这样我们就只需要考虑加法和进位,最后加完每一位后就是最终结果了。

思路:

分别用两个指针( i,j )在两个数字(num1,num2)的每一位中循环。res=num1[i] * num2[j]。每次将结果累加到对应的位置。res对应的位置是str[i+j],str[i+j+1]。最后得出结果。

C++ 代码 class Solution {public: string multiply(string num1, string num2) { if(num1=="0"||num2=="0") return "0";//当num1或者num2为0时直接返回0 int len1=num1.size(),len2=num2.size(); vector<int> vec(len1+len2);//初始化一个最大的结果容器,里面的内容全为0 string res="";//存储结果 int carry=0; for(int i=len1-1;i>=0;i--){ for(int j=len2-1;j>=0;j--){ int mul=(num1[i]-'0')*(num2[j]-'0');//每位相乘的结果 int p1=i+j,p2=i+j+1;//相乘后应放到对应的结果[i+j,i+j+1] int sum=mul+vec[p2];//累加到sum上 vec[p2]=sum%10; vec[p1]+=sum/10; //加上进位的结果进位 } } for(int i=0;i<vec.size();i++){ if(i==0&&vec[i]==0){ continue;//如果第一位为0 说明前缀没有使用,则去掉前缀为0的情况。 } res.push_back(vec[i]+'0'); } return res; }};

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。