51Nod-1005 大数加法
2018-01-05 19:57
381 查看
如题
这是一道很简单的基础题,当年大一的时候在自己学校的oj上做过这道题的简单版,不过没做出来,现在转眼好几年了,算法一直不好,于是重新来练练手。
这道题用java或者python等语言可以用很短的代码写出来,但那没意义了,所以我用的是c++。
思路很简单,无非用字符型数组保存即可。
但是这道题因为有负数,所以负数必须分类讨论。
如果两个都是负数,好办,直接输出一个负号,然后按正数加法对数字进行运算即可。
如果一个正数一个负数,就需要额外设计一个减法了。
然后长度的话,虽然做题的时候数组空间的申请都讲究要比它说的大一点,但我一开始想着既然范围是不超过10000,申请10000不就够了么,果然天真的我就错了,没考虑进位,居然还出现了RTE,哎呀呀。
中间还出现了一个问题,因为要循环输入嘛,里面循环调用的非main函数里面的局部变量的值每次都是一样的,注意是局部变量,写java写惯了的我觉得很奇怪,相关细节请参看我的另一篇博客:由c++循环中局部变量地址不变而引发的思考
下面放上我冗长的代码(一些边边角角能省的都省了/笑)
这是一道很简单的基础题,当年大一的时候在自己学校的oj上做过这道题的简单版,不过没做出来,现在转眼好几年了,算法一直不好,于是重新来练练手。
这道题用java或者python等语言可以用很短的代码写出来,但那没意义了,所以我用的是c++。
思路很简单,无非用字符型数组保存即可。
但是这道题因为有负数,所以负数必须分类讨论。
如果两个都是负数,好办,直接输出一个负号,然后按正数加法对数字进行运算即可。
如果一个正数一个负数,就需要额外设计一个减法了。
然后长度的话,虽然做题的时候数组空间的申请都讲究要比它说的大一点,但我一开始想着既然范围是不超过10000,申请10000不就够了么,果然天真的我就错了,没考虑进位,居然还出现了RTE,哎呀呀。
中间还出现了一个问题,因为要循环输入嘛,里面循环调用的非main函数里面的局部变量的值每次都是一样的,注意是局部变量,写java写惯了的我觉得很奇怪,相关细节请参看我的另一篇博客:由c++循环中局部变量地址不变而引发的思考
下面放上我冗长的代码(一些边边角角能省的都省了/笑)
#include<bits/stdc++.h> using namespace std; void doCut(char *a,char *b) { //cout<<endl<<"a="<<a<<" b="<<b<<endl; int jie=0; int alen=strlen(a)-1; int blen=strlen(b)-1; int c[10005]={'\0'}; int a1=0,b1=0,c1=0; while(alen>=0 && blen>=0) { c[c1] = a[alen]-b[blen]-jie; if(c[c1] < 0) { jie=1; c[c1] +=10; } else { jie=0; } c1++; alen--; blen--; } while(alen>=0) { c[c1] = a[alen]-'0'-jie; if(c[c1] < 0) { jie=1; c[c1]+=10; } else{ jie=0; } c1++; alen--; } int d=0; for(int i=c1--;i>=0;i--) { if(d == 0) { if(c[i] == 0) continue; d=1; } cout<<c[i]; } cout<<endl; } void dothat(char *a,char *b) { int alen = strlen(a) -1; int blen = strlen(b) -1; int a1=0,b1=0; if(alen > blen) { cout<<"-"; doCut(a,b); return; } if(alen < blen) { doCut(b,a); return; } while(blen >= 0) { //cout<<a[a1]<<"--"<<b[b1]<<endl; if(a[a1] > b[b1]) { cout<<"-"; doCut(a,b); return; } if(a[a1++] < b[b1++]) { doCut(b,a); return; } blen--; } cout<<0<<endl; } void doJudge(char *a,char *b) { char d[10005]={'\0'}; if(a[0] == '-') { for(int i=1;i<strlen(a);i++) { d[i-1]=a[i]; } //cout<<endl<<"^^^^"<<d<<endl; dothat(d,b); } else { for(int i=1;i<strlen(b);i++) { d[i-1]=b[i]; } dothat(d,a); } } void init(char *a,char *b) { for(int i=0;i<10005;i++) { a[i]='\0'; b[i]='\0'; } } int main() { char a[10005]; char b[10005]; while(cin>>a>>b) { int c[10005] = {'\0'}; int a1=0,b1=0; int alen = strlen(a) -1; int blen = strlen(b) -1; int clen=0; if(a[0]=='-' && b[0]=='-') { //加法 if(a[1] !='0' || b[1] !='0') cout<<"-"; a1++; b1++; } else if(a[0] == '-' || b[0] == '-') { //减法 doJudge(a,b); init(a,b); continue; } int jin = 0; //加法 while(alen>=a1 && blen>=b1) { c[clen] = a[alen]-'0' + b[blen] -'0' + jin; if(c[clen] > 9) { jin=1; c[clen] %= 10; } else { jin=0; } //cout<<c[clen]<<endl; clen++; alen--; blen--; } while(alen >= a1) { //cout<<endl<<"alen >= a1"<<endl; c[clen] = a[alen--]-'0'+jin; if(c[clen] > 9) { jin=1; c[clen] %= 10; } else { jin=0; } clen++; } while(blen >= b1) { //cout<<endl<<"blen >= b1"<<endl; c[clen] = b[blen--]-'0'+jin; if(c[clen] > 9) { jin=1; c[clen] %= 10; } else { jin=0; } clen++; } if(jin == 1){ c[clen++] = 1; } int tt=0; int emptyt = 0; for(--clen; clen>=0; clen--) { if(tt==0) { if(c[clen] == 0) continue; tt=1; } emptyt=1; cout<<c[clen]; } if(emptyt==0) cout<<0; cout<<endl; init(a,b); } return 0; }
相关文章推荐
- 51nod 1005 大数加法
- 51Nod-1005 大数加法
- 51nod 1005 大数加法
- 51nod 1005 大数加法
- 51Nod 1005 大数加法
- 51nod 1005 大数加法
- 51nod 1005 大数加法
- 51nod 1005 大数加法
- 51Nod - 1005 大数加法
- 51nod 1005 大数加法
- 【51Nod】1005 大数加法
- 51nod 1005 大数加法
- 51Nod-1005-大数加法
- 51Nod 1005 大数加法
- 51nod——1005 大数加法
- 【51nod】1005 大数加法
- 51nod-1005 大数加法
- 51nod 1005 大数加法(可为负数)
- 51nod_1005 大数加法
- 大数高精度加减乘除 51nod 1005 大数加法