本代码可以获取命令行输入的数字和加减运算

因为较大整数的相加很可能超出整型的32位限制,或者本身就是超出限制的大数之间的加减运算。

所以我们需要单独写一个能大数相加减的函数

基本原理:把数字用字符串的形式来保存加减的结果或大数字本身就不会超出限制,比如“999999999999999999999999999999” 多长都可以

一.加法

从右往左加,要考虑相加超过10,向前进位(用bool类型的标记),个位数则push_back进结果容器中

还要考虑相加的两个字符串分别有位数剩余的情况,即比如string1比string2更长,或反之。

二.减法

考虑相减为负数,所以要先找出更大的字符串(先看是否更长),再看长度一样时哪个更大(可以直接字符串比较),让大的减小的,负号后面再加上去

而且相减时往往还需要向上一位借个1,如2 - 6,应该是12 - 6,所以为 2 - 6 + 10 = 6

也就是说,个位相减后再+10

三.改进

因为是由低到高push_back进数组,再reverse,所以push进去时,是10000,反转后是00001,我们应该去掉多余的0,让其输出1;——写个while循环解决

另外,由控制台输入数据比写死在代码中好,将其读取为字符串,注意getline(cin, m)的第二个参数只能是string类型的,所以+和-也得定义为string类型

运行结果展示:

大数相减:

1的前面没有多余的0
大数相加:

完整代码:

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;class BigInt
{public:BigInt(string str) : strDigit(str){ }
private:string strDigit;//使用字符串存储大整数//都是全局函数声明为友元friend ostream& operator<<(ostream& out, const BigInt& src);friend BigInt operator+(const BigInt& lhs, const BigInt& rhs);friend BigInt operator-(const BigInt& lhs, const BigInt& rhs);};
//打印函数
ostream& operator<<(ostream& out, const BigInt& src)
{out << src.strDigit;return out;
}//大数加法
BigInt operator+(const BigInt& lhs, const BigInt& rhs) {//从后往前遍历字符串lhs,和rhs,用flag来标记是否需要进位,结果存在result数组中(反向的)string result;bool flag = false;int i = lhs.strDigit.length() - 1;//string的length和size没有区别,length是沿用C语言习惯,早先只有lengthint j = rhs.strDigit.length() - 1;for (; i >= 0 && j >= 0; --i, --j) //i 和 j其中一个会被减到负数然后退出for循环{int ret = lhs.strDigit[i] - '0' + rhs.strDigit[j] - '0';//单个位加减时需要减'0'转成整型,每次都重新定义一个新的retif (flag){ret += 1;//flag为true说明此位因为上一位进位而需要多加一个1flag = false;//再将其重新置为false}//两个if不能互换,否则不是下一位进1if (ret >= 10){ret %= 10;flag = true;}result.push_back(ret + '0');}//如果遍历完,i还有剩下,第一个字符串没完if (i >= 0)//注意要取等,因为更短的那个字符串的下标是被减到-1,而不是0,0依然说明还剩余1位{while (i >= 0){int ret = lhs.strDigit[i] - '0';if (flag)                 //前面加过来可能还有进位,然后当前可能为9,加了1之后又 = 10,又得进位,所以直接复制前面的代码{ret += 1;flag = false;}if (ret >= 10){ret %= 10;flag = true;}result.push_back(ret + '0');i--;  }}//第二个字符串没完else if (j >= 0){while (j >= 0){int ret = lhs.strDigit[j] - '0';if (flag)                 //前面加过来可能还有进位,然后当前可能为9,加了1之后又 = 10,又得进位,所以直接复制前面的代码{ret += 1;flag = false;}if (ret >= 10){ret %= 10;flag = true;}result.push_back(ret + '0');j--;}}//最高位可能也进位if (flag) {result.push_back('1');}reverse(result.begin(), result.end());return result;//result是string类,而不是BigInt,因为隐式转换,p263//因为编译器看到该类的构造函数只接受一个实参(而且是string类的),所以可以触发隐式转换机制,定义string result时编译器也会构建一个BigInt类的临时对象,并把result赋值给他//函数里的return本来就是返回临时对象,这个时候就返回的就是那个BigInt类的临时对象//当然,参考书上的例子,即使后面函数用string类的result,编译器实际传入的也是BigInt的临时对象//如某成员函数定义为func(BigInt& a){...}; 调用时传入string类 func(result);也是合法的
}//大数减法
BigInt operator-(const BigInt& lhs, const BigInt& rhs) {//让大的减小的,如果lhs比rhs小,则让rhs - lhs,然后最后添加负号string result;bool flag = false;bool minor = false;//标记lhs是否和rhs互换了string maxStr = lhs.strDigit;string minStr = rhs.strDigit;if (maxStr.length() < minStr.length()){//互换,让maxStr一直是最长的maxStr = rhs.strDigit;minStr = lhs.strDigit;minor = true;}//长度一样也得比较else if (maxStr.length() == minStr.length()){if (maxStr < minStr){maxStr = rhs.strDigit;//让maxStr是最大的minStr = lhs.strDigit;minor = true;}else if (maxStr == minStr){return string("0");}}int i = maxStr.length() - 1;//i肯定大于等于j,所以后面j会先完int j = minStr.length() - 1;for (; i >= 0 && j >= 0; --i, --j) {int ret = maxStr[i]  - minStr[j];//减法的话,char类型相减就是int型了,不用+‘0’再相减/*if (ret >= 0){result.push_back(ret + '0');} 一定要先看标记,因为被借位的话,当前ret需要减1*/if (flag){ret -= 1;flag = false;}//当前位有可能因为被借位了而减,小于0,所以紧接着判断是否为负if (ret < 0){ret += 10;// 如2 - 6,应该是12 - 6,所以为 2 - 6 + 10 = 6flag = true;}result.push_back(ret + '0');}//肯定是j先完,所以不用再像加法那样判断,而是直接把i多余的处理完while (i >= 0) {int ret = maxStr[i] - '0';if (flag) {ret -= 1;flag = false;}//同样的,ret可能原本是0,被借位了又为-1了if (ret < 0) {ret += 10;flag = true;}result.push_back(ret + '0');i--;}//翻转前先看看末尾有没有0,如1000,否则反转后就是0001while(result.back() == '0'){result.pop_back();}if (minor) {result.push_back('-');}reverse(result.begin(), result.end());return result;
}int main()
{string s1;string A;string s2;getline(cin, s1);getline(cin, A);//把加减号定义为char会报错,getline第二个参数只能是string类型getline(cin, s2);BigInt int1(s1);BigInt int2(s2);if (A == "+") {cout << int1 + int2 << endl;}if (A == "-") {cout << int1 - int2 << endl;}return 0;
}

C++实现大数加减法相关推荐

  1. java小学生加减法_大数加减法 - java实现

    计算机处理的各种数据类型都有个范围,超出范围的就处理不了. 如果做超大数运算加减乘除,普通方法肯定是不行的,那么我们遇到大数的运算怎么处理呢?今天介绍一种大数加减乘除运算的方法 思路: 1. 将两个特 ...

  2. 大数算法之大数加减法

    大数算法之大数加减法 当我们第一次编程,成功地在黑洞洞的控制台窗口中打印出"Hello World"的字符后,准备编写的第一个有实用性的程序是什么?我想,对于大多数人而言,这一问题 ...

  3. 利用C语言实现大数加减法

    大数加法: #include <stdio.h> #include <string.h> #define M 100 //定义了数量M是100作为数组初始化的数量 int ma ...

  4. c语言大数位加法,求用C编个大数加减法运算程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 只写过加法的,杭电的A + B Problem (II)(AC): #include #include #include #define N 3000 i ...

  5. c语言大数的加减运算,求用C编个大数加减法运算程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 只写过加法的,杭电的A + B Problem (II)(AC): #include #include #include #define N 3000 i ...

  6. 用c语言编程减法计算,求用C编个大数加减法运算程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 只写过加法的,杭电的A + B Problem (II)(AC): #include #include #include #define N 3000 i ...

  7. c语言计算多个整数加减,求用C编个大数加减法运算程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 只写过加法的,杭电的A + B Problem (II)(AC): #include #include #include #define N 3000 i ...

  8. c语言编写五十以内加减法,求用C编个大数加减法运算程序

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 只写过加法的,杭电的A + B Problem (II)(AC): #include #include #include #define N 3000 i ...

  9. 大数乘法(快速傅立叶变换)下

    博客搬家:最爱午后红茶 大数乘法(快速傅立叶变换)上 上篇已经已经讲了多项式乘法由系数表示法转化为点值表示法(即求值)的FFT算法的过程:接下来讲插值算法,它需不需要用新的算法写一遍呢?并不用这么麻烦 ...

最新文章

  1. 量子信息技术研究现状与未来——郭光灿
  2. 1-NET UX1000-实战-配置-Lync Server 2010-集成
  3. Linux VNC黑屏(转)
  4. Java Spring MVC model学习
  5. linux系统限制内存使用率,linux中限制CPU和内存占用率方法
  6. 100个灯泡python编程_算法题:一个圆环上有100个灯泡,灯泡有打...
  7. 骨牌覆盖问题总结!hihoCoder/ NYOJ-1273宣传墙1151
  8. 台积电南京12寸厂址 落脚江北新区
  9. Java基础 --存储数据
  10. docker 部署 zookeeper+kafka 集群
  11. 哗啦啦收银机系统服务器异常,解决哗啦啦收银系统数据库备份问题(示例代码)...
  12. Ubuntu18.04版本安装ssh及连接ssh的常见问题
  13. 安全防护重在数据 人才选拔重在心力、脑力、体力
  14. The Bean Validation API is on the classpath but no implementation could be found 项目启动报错解决
  15. 新旧骗术揭秘:防止5G时代的电信诈骗
  16. Excel 透视图数据源无效的问题(PivotTable Data Source Not Valid)
  17. 跟着CELL学作图|1.火山图
  18. 编程,从来都不晚:来自日本的82岁APP开发者
  19. 最新游戏陪玩源码V2.0升级版/商业版语音聊天系统源码
  20. asp.net ajax1.0基础回顾(二):经典模式

热门文章

  1. HTML+CSS项目实践四:给html网页标题栏添加logo图标(ico格式图片)
  2. python图像处理(二)绘制函数图像
  3. Yigo平台中系统自带的五个系统字段值
  4. 10.statement对象实例(executeUpdate方法以及executeQuery方法),JDBC工具类编写
  5. Qt的Q_UNUSED()函数的功能
  6. yuv rgb 互转 公式 及算法
  7. 数据库:数据的独立性
  8. 微信小程序调用导航,uniapp打开本地导航软件
  9. Hibernate - Java 类型, Hibernate 映射类型及 SQL 类型之间的对应关系
  10. 机器视觉:热成像相机选择的五大因素