挑战面试编程:大整数的加、减、乘、除
来源:互联网 发布:淘宝如何设置单件包邮 编辑:程序博客网 时间:2024/06/02 23:59
挑战面试编程:大整数的加、减、乘、除
一切都是有限的,哪怕是看起来无限的时间或空间都很可能是有限的。在计算机中内置类型的加、减、乘、除都是有限的。我们来实现一个“无限”的大整数加、减、乘、除。
以下使用C++代码实现
#include <iostream>#include <string>using namespace std;//大整数的加减乘除string add_int(string, string);string sub_int(string, string);string mul_int(string, string);string div_int(string, string);string mod_int(string, string);string divide_int(string, string, int);inline int compare(string s1, string s2){if (s1.size() < s2.size())return -1;else if (s1.size() > s2.size())return 1;elsereturn s1.compare(s2);}/*大整数加法本质上只处理:两个正数相加,如 "123" + "234"其它情况需转化1. 正加负 => "123" + "-234" = "123" - "234" 转化为减法2. 负加正 => "-234" + "123" = "123" - "234"3. 负加负 => "-123" + "-234" = -("123" + "234")*/string add_int(string s1, string s2){if (s1 == "0")return s2;if (s2 == "0")return s1;if (s1[0] == '-'){if (s2[0] == '-'){return "-" + add_int(s1.erase(0, 1), s2.erase(0, 1)); //情况三}else{return sub_int(s2, s1.erase(0, 1)); //情况二}}if (s2[0] == '-'){return sub_int(s1, s2.erase(0, 1)); //情况一}//处理本质情况string::size_type i, size1, size2;size1 = s1.size();size2 = s2.size();if (size1 < size2){for (i = 0; i < size2 - size1; i++) //在s1左边补零s1 = "0" + s1;}else{for (i = 0; i < size1 - size2; i++) //在s2左边补零s2 = "0" + s2;}int n1, n2;n2 = 0;size1 = s1.size();size2 = s2.size();string res;for (i = size1 - 1; i != 0; i--) //从最低位加起{n1 = (s1[i] - '0' + s2[i] - '0' + n2) % 10; //n1代表当前位的值n2 = (s1[i] - '0' + s2[i] - '0' + n2) / 10; //n2代表进位res = char(n1 + '0') + res;}/*上述循环不能处理第0位的原因在于i的类型是string::size_type,它是非负类型*///对于第0位单独处理n1 = (s1[0] - '0' + s2[0] - '0' + n2) % 10;n2 = (s1[0] - '0' + s2[0] - '0' + n2) / 10;res = char(n1 + '0') + res;if (n2 == 1)res = "1" + res;return res;}/*大整数减法本质上只处理:两整数相减,并且是一大减一小:"1234" - "234"其它情况需转化1. 小正减大正 => "234" - "1234" = -("1234" - "234")2. 正减负 => "1234" - "-234" = "1234" + "234"3. 负减正 => "-1234" - "234" = -("1234" + "234")4. 负减负 => "-1234" - "-234" = "234" - "1234" = -("1234" - "234")*/string sub_int(string s1, string s2){if (s2 == "0")return s1;if (s1 == "0"){if (s2[0] == '-')return s2.erase(0, 1);return "-" + s2;}if (s1[0] == '-'){if (s2[0] == '-'){return sub_int(s2.erase(0, 1), s1.erase(0, 1)); //情况四}return "-" + add_int(s1.erase(0, 1), s2); //情况三}if (s2[0] == '-')return add_int(s1, s2.erase(0, 1)); //情况二//调整s1与s2的长度string::size_type i, size1, size2;size1 = s1.size();size2 = s2.size();if (size1 < size2){for (i = 0; i < size2 - size1; i++) //在s1左边补零s1 = "0" + s1;}else{for (i = 0; i < size1 - size2; i++) //在s2左边补零s2 = "0" + s2;}int t = s1.compare(s2);if (t < 0) //s1与s2的size相同,但 s1 < s2return "-" + sub_int(s2, s1);if (t == 0)return "0";//处理本质情况:s1 > s2string res;string::size_type j;for (i = s1.size() - 1; i != 0; i--){if (s1[i] < s2[i]) //不足,需向前借一位{j = 1;while (s1[i - j] == '0'){s1[i - j] = '9';j++;}s1[i - j] -= 1;res = char(s1[i] + ':' - s2[i]) + res;}else{res = char(s1[i] - s2[i] + '0') + res;}}res = char(s1[0] - s2[0] + '0') + res;//去掉前导零res.erase(0, res.find_first_not_of('0'));return res;}string mul_int(string s1, string s2){if (s1 == "0" || s2 == "0")return "0";//sign是符号位int sign = 1;if (s1[0] == '-'){sign *= -1;s1.erase(0, 1);}if (s2[0] == '-'){sign *= -1;s2.erase(0, 1);}string::size_type size1, size2;string res, temp;size1 = s1.size();size2 = s2.size();//让s1的长度最长if (size1 < size2){temp = s1;s1 = s2;s2 = temp;size1 = s1.size();size2 = s2.size();}int i, j, n1, n2, n3, t;for (i = size2 - 1; i >= 0; i--){temp = "";n1 = n2 = n3 = 0;for (j = 0; j < size2 - 1 - i; j++) temp = "0" + temp;n3 = s2[i] - '0';for (j = size1 - 1; j >= 0; j--){t = (n3*(s1[j] - '0') + n2);n1 = t % 10; //n1记录当前位置的值n2 = t / 10; //n2记录进位的值temp = char(n1 + '0') + temp;}if (n2)temp = char(n2 + '0') + temp;res = add_int(res, temp);}if (sign == -1)return "-" + res;return res;}string divide_int(string s1, string s2, int flag) //flag=1,返回商;flag=0,返回余数{string quotient, residue;if (s2 == "0"){quotient = residue = "error";if (flag == 1)return quotient;elsereturn residue;}if (s1 == "0"){quotient = residue = "0";if (flag == 1)return quotient;elsereturn residue;}//sign1是商的符号,sign2是余数的符号int sign1, sign2;sign1 = sign2 = 1;if (s1[0] == '-'){sign1 *= -1;sign2 = -1;s1.erase(0, 1);}if (s2[0] == '-'){sign1 *= -1;s2.erase(0, 1);}if (compare(s1, s2) < 0){quotient = "0";residue = s1;}else if (compare(s1, s2) == 0){quotient = "1";residue = "0";}else{string temp;string::size_type size1, size2;size1 = s1.size();size2 = s2.size();int i;if (size2 > 1) temp.append(s1, 0, size2 - 1);for (i = size2 - 1; i < size1; i++){temp = temp + s1[i];//试商for (char c = '9'; c >= '0' ; c--){string t = mul_int(s2, string(1, c));string s = sub_int(temp, t);if (s == "0" || s[0] != '-'){temp = s;quotient = quotient + c;break;}}}residue = temp;}//去除前导零quotient.erase(0, quotient.find_first_not_of('0'));residue.erase(0, residue.find_first_not_of('0'));if (sign1 == -1){quotient = "-" + quotient;}if (sign2 == -1){if (residue.empty())residue = "0";elseresidue = "-" + residue;}if (flag == 1) return quotient;else return residue;}string div_int(string s1, string s2){return divide_int(s1, s2, 1);}string mod_int(string s1, string s2){return divide_int(s1, s2, 0);}int main(void){string s1, s2;char op;while (cin >> s1 >> op >> s2){switch (op){case '+':cout << add_int(s1, s2) << endl; break;case '-':cout << sub_int(s1, s2) << endl; break;case '*':cout << mul_int(s1, s2) << endl; break;case '/':cout << div_int(s1, s2) << endl; break;case '%':cout << mod_int(s1, s2) << endl; break;default:cout << "The operator is error!" << endl; break;}}return 0;}
c语言实现大整数加法的实例
#include <stdio.h>#include <string.h>#define MAXLEN 1000char a1[MAXLEN];char a2[MAXLEN];static int v1[MAXLEN];static int v2[MAXLEN];static int v3[MAXLEN];int i, j, n, L, z;void main(void) {scanf("%d", &n);for (j = 0; j < n; j++) {scanf("%s%s", a1, a2);L = strlen(a1);for (i = 0; i < L; i++) v1[i] = a1[L - 1 - i] - '0'; //下标越小,位数越高L = strlen(a2);for (i = 0; i < L; i++) v2[i] = a2[L - 1 - i] - '0';for (i = 0; i < MAXLEN; i++) v3[i] = v1[i] + v2[i];for (i = 0; i < MAXLEN; i++) {if (v3[i] >= 10) {v3[i + 1] += 1;v3[i] = v3[i] % 10;}}printf("Case %d:\n", j + 1);printf("%s + %s = ", a1, a2);z = 0;for (i = MAXLEN - 1; i >= 0; i--) {if (z == 0) {if (v3[i] != 0) {printf("%d", v3[i]);z = 1;}}else {printf("%d", v3[i]);}}if (z == 0) printf("0");printf("\n");}getchar();getchar();}//Sample Input//3//0 0//1 2//112233445566778899 998877665544332211////Sample Output//Case 1://0 + 0 = 0//Case 2://1 + 2 = 3//Case 3://112233445566778899 + 998877665544332211 = 1111111111111111110
代码下载
大整数的加、减、乘、除 C++
所有内容的目录
- CCPP Blog 目录
2 0
- 挑战面试编程:大整数的加、减、乘、除
- 大整数的加乘多项式运算
- 模拟大整数加、减、乘、除法
- 对两个整数进行加、减、乘、除
- 复数类的加,减,乘,除
- 数的加 减 乘 除
- BigDecimal的加 减 乘 除
- BigDecimal的加、减、乘、除
- 大数 加 减 乘 除
- Linux 加,减,乘,除
- 大数的加,减,乘,除,乘方运算
- linux下的shell运算(加、减、乘、除)
- 解决大数的,加、减、乘、除问题
- OC---分数的加、减、乘、除、比较大小
- BigDecimal 类型数据的加、减、乘、除以及格式化
- java 浮点数的加、减、乘、除工具类
- js加、减、乘、除的精度问题
- Java中Double型数据的加,减,乘,除
- 分享到QQ空间的icon的坑
- C#接口
- MYSQL使用group by时,查询结果的总记录数
- 80后的互联网北漂:你的未来在哪?
- 用java写的C语言词法分析
- 挑战面试编程:大整数的加、减、乘、除
- Android 编程下通过 Theme 和 Style 避免 APP 启动闪黑屏
- 编程之美 之 让CPU占用率听你指挥
- jsp页面的ajax取值
- Android 避免APP启动闪黑屏(Theme和Style)
- 前端菜鸟的成长学习之路(一)
- YGM欧版磨粉机微粉磨生产线
- 数据持久化(一)-----归档 读写 文件路径
- PB如何连接mysql数据库