415. 字符串相加


题意:给定两个字符串形式的非负整数 num1 和num2 ,计算它们的和。

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

说明:

  • 1、num1 和num2 的长度都小于 5100
  • 2、num1 和num2 都只包含数字 0-9
  • 3、num1 和num2 都不包含任何前导零
  • 4、你不能使用任何內建 BigInteger 库, 也不能直接将输入的字符串转换为整数形式

思路:

这道题主要考察对字符串的模拟,模拟两个整数相加的情况。

来看看我们做加法的情况。

步骤:

■ 1、从每个数从低位到高位依次相加,包括进位的数字。

■ 2、判断当前相加的数是否超过10,如果超过10往前进位,然后当前数减去10。

■ 3、循环步骤一和步骤二,直到把字符串遍历完。

■ 4、检查最后是否有进位,如果有进位,将进位加上,最后得到就是我们的结果。

提示:

■ 1、因为我们不确定最后结果的长度,所以我们常常将得到的每一位结果依次往结果字符串当中增加,这样得到的结果是反的,所以最后我们需要将结果字符串反转。

■ 2、我们处理每个字符串时,从最高位处理,最高位对应的是数字中的最低位。

C++ 代码

class Solution {public:string addStrings(string num1, string num2) {string res; //存储结果字符串int i=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((carry%10)+'0');//算得本位应该是多少carry/=10; //算的是否进位i--,j--;}if(carray)res.push_back(carray+'0');//检查最后是否还有进位reverse(res.begin(),res.end()); //得到的结果是反的所以要将字符串反转,变成最终的结果return res;}
};

解决了这道题,可以去解决以下几道题:

1、LeetCode 445. 两数相加 II

2、LeetCode 66. 加一


高精度减法

题意:给定两个正整数,计算它们的差,计算结果可能为负数。

输入格式:共两行,每行包含一个整数。

输出格式:共一行,包含所求的差。

数据范围:1≤整数长度≤10^5

输入样例:

32
11

输出样例:

21

思路:

这道题主要考察对字符串的模拟,模拟两个整数相减的情况。

来看看我们做减法的情况。(和加法类似)

步骤:

■ 1、用大数的每一位数减去小数的每一位数,每个数从低位到高位依次相减,包括借位。

■ 2、判断当前每个位上的数相减是否小于0。如果小于0往前借一位数,然后当前数加上10,借位置成1。否则不借位,借位置成0。然后算得当前数的结果,存入结果字符串中。

■ 3、循环步骤一和步骤二,直到把字符串遍历完。

■ 4、检查最后字符串中是否包含前导0。如果存在去掉前导0,最后将结果字符串反转。

提示:

■ 1、因为我们不确定最后结果的长度,所以我们常常将得到的每一位结果依次往结果字符串当中增加,这样得到的结果是反的,所以最后我们需要将结果字符串反转。我们可以将输入的两个整数的每一位存入容器中来进行处理。

■ 2、我们处理每个字符串时,从最高位处理,最高位对应的是数字中的最低位。

C++ 代码

#include<iostream>
#include<vector>
using namespace std;//return A>=B
bool cmp(vector<int>&A,vector<int>&B){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,所以去掉前导0return 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 的长度都小于 110
  • 2、num1 和num2 都只包含数字 0-9
  • 3、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 * 2789 * 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时直接返回0int len1=num1.size(),len2=num2.size();vector<int> vec(len1+len2);//初始化一个最大的结果容器,里面的内容全为0string 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;}
};

LeetCode大数运算相关推荐

  1. C语言实现大数运算(长整数的加、减、乘、除)

    由于整型数的位数有限,因此整型数不能满足大整数(超长整数)的运算要求 .大整数计算是利用字符串来表示大整数,即用字符串的一位字符表示大整数的一位数值,然后根据四则运算规则实现大整数的四则运算. 简单表 ...

  2. C语言学习趣事_之_大数运算_加法

    C语言学习趣事_大数运算_之加法 1.引子    在C语言中,因为预定义的自然数类型的大小是有上下限度的,这就决定了在进行数的运算的时候,必然受到限制,同时因为C语言是最接近汇编的一种程序设计语言,并 ...

  3. java中大数开方_Java中的大数运算

    # 一:大数运算出现的背景 java里面整型int与浮点型float,double它们存放数据的范围是有限的,当出行更大的数值时会发生溢出. 最典型的场景是金融行业,直接使用单精度或者双精浮点数来表示 ...

  4. Openssl 之大数运算函数 BN

    Openssl 之大数运算函数 BN 主要介绍Openssl中的有关大数运算函数,这个对于RSA研究和实现比较有价值   1.初始化函数 BIGNUM *BN_new(void);    新生成一个B ...

  5. 【PAT甲级 大数运算】1065 A+B and C (64bit) (20 分) Python 全部AC

    题目 初学python,第一次用python刷oj,挑了个简单题试试手. 在大数运算方面,python没有数的大小限制,简直开挂. total = int(input()) for i in rang ...

  6. Java的学习与java大数运算

    之前就学过一点java,但太久没用知识点早就还给书本,之前在实验室搞到一本java的书,今天来重新温习一下 java的语法大部分和c++语言是一样的,入门非常快,所以在这里基础语句的用法就省略了 输出 ...

  7. 备忘: MIRACL 大数运算库使用手册

    <MIRACL 大数运算库使用手册> 作者: 游贵荣 中文使用手册: http://blog.csdn.net/shuilan0066/article/details/8520337htt ...

  8. 算法之大数运算加减法源代码

    很多小伙伴对计算机编程的算法感兴趣,但在很多竞赛类算法网站中,大数运算往往是必考的,而课本有基本未提及,所以,今天来提供算法的基本运算的源码(加减). 对于大多数大数运算,往往是超出int 的范围,比 ...

  9. 黄金连分数(斐波那契数列、大数运算)正确解法

    标题: 黄金连分数     黄金分割数0.61803... 是个无理数,这个常数十分重要,在许多工程问题中会出现.有时需要把这个数字求得很精确. 对于某些精密工程,常数的精度很重要.也许你听说过哈勃太 ...

最新文章

  1. UVa OJ 120
  2. Github continuous deployment (CD) 最佳实践
  3. .NET Core IdentityServer4实战 第Ⅳ章-集成密码登陆模式
  4. Linux内核配置系统浅析
  5. Quartus II 8.1 详解--有图---图片详解 【1讲】
  6. iPhone SplitViewController
  7. mysql集群(一)
  8. 【论文】最新自然语言处理领域顶会论文大合集!
  9. L1-051 打折 (5 分)—团体程序设计天梯赛
  10. M1芯片mac好用吗?来听听ta们是怎么说的
  11. 实对称矩阵的特征值求法_【8】实(反)对称矩阵的特征值
  12. Nginx面试题整理
  13. 统计学——单因素方差分析
  14. visual studio 2008 提示 “函数xxx 已有主体”
  15. 中国互联网公司如何进军海外,先行者六点血泪教训
  16. okhttp使用总结
  17. 勤于奋:国外LEAD账号申请细节
  18. linux meld
  19. Ubuntu系统释放磁盘空间
  20. 【学习笔记】GPS测量与数据处理(观测值的线性组合(单差、双差、三差))

热门文章

  1. JBOSS EAP实战(1)
  2. 换了个无线怎么找到服务器,路由器再接一个路由器怎么设置? | 192路由网
  3. 武汉科技大学计算机学院院长邮箱,武汉科技大学计算机科学与技术学院院长张晓龙来校讲学...
  4. 英文字母的大小写转换2
  5. 【排序算法】冒泡排序(动图演示) - 保姆级详解
  6. Matlab实现人眼精准识别和定位
  7. 遥感里通过夜间灯光数据提取城市建成区步骤(保姆级教学)
  8. Python实现多项式回归实战——以及与线性回归的拟合效果对比
  9. 进程控制和通信(四)
  10. Java--时间换算例子