代码解释都用注释写在旁边了
解题思路:
一步步来就没问题
注意事项:
上题过了这题就一遍过;
可能要有的:
①忽略前导0 如009+001-002这样的
②直接回车也输出0
参考代码:
#include<stdio.h> const int N=1e4+5;//上题用的常数 inline void swap(int &a,int &b){int c=a;a=b;b=c;}//交换 inline void deal(int *a)//把009变成900的左右颠倒函数 { int len=a[0]>>1;//移位运算符,相当于/2 for(int i=1;i<=len;++i)swap(a[i],a[a[0]+1-i]); } void out(int *a){for(int i=a[0]?a[0]:1;i>0;--i)printf("%d",a[i]);/*putchar(10);*/}//输出结果的函数 inline void add(int *a,int *b)//高精度加法 { a[0]=(a[0]>b[0]?a[0]:b[0])+1;//取两个长度中较长的并且+1,因为最高的位数在相加时可能会进1 如9+1=10 b[0]=0;//清理数组 for(int i=1;i<=a[0];++i) { a[i]+=b[i]; b[i]=0;//顺便清理数组 if(a[i]>9)a[i]-=10,++a[i+1];//进位 } while(a[0]>1&&!a[a[0]])--a[0];//至少保留1位,同时去除前导0 } inline void subtraction(int *a,int *b) { a[0]=a[0]>b[0]?a[0]:b[0];//从上面抄下来的。因为是减法没有+1也行 b[0]=0;//清理数组 for(int i=1;i<=a[0];++i) { a[i]-=b[i]; b[i]=0;//顺便清理数组 if(a[i]<0)a[i]+=10,--a[i+1];//借位 } while(a[0]>1&&!a[a[0]])--a[0];//至少保留1位,同时去除前导0 } inline void yunsuan(const char &op,int *a,int *b) { deal(b);//运算前先处理b数组 switch(op)//根据上次的运算符决定进行什么运算 { case('+'):add(a,b);return; case('-'):subtraction(a,b);return; default:return; } } inline bool check(const char &k,char &op,int *a,int *b)//看看这个是运算符还是数字还是别的 { switch(k) { case('+'):yunsuan(op,a,b),op=k;return 1;//运算在前面是因为op是上次没算的运算符。 实际上1+1-1 是读到减号的时候才开始算加号的 case('-'):yunsuan(op,a,b),op=k;return 1; case('*'):yunsuan(op,a,b),op=k;return 1; case('/'):yunsuan(op,a,b),op=k;return 1; case('^'):yunsuan(op,a,b),op=k;return 1; default:return 0; }//1是运算符,0不是 } int a[N],b[N];//a是结果数组,b是临时数组,a[0],b[0]为数组长度 char op,k;//op是上次的运算符,k是用来读字符的变量 bool key,mark;//key用于去除前导0,mark判断a有没有被处理过,处理过才能用out()输出 main() { while(k!=-1&&k!=10&&~(k=getchar()))//如果读取到回车或EOF就退出 { if(check(k,op,a,b))//看看这个是运算符还是数字还是别的 { deal(a); key=0;//每次读取数字都要关闭,说明还没处理前导0 mark=1;//处理过a数组的标志 while(~(k=getchar())&&k!=10)//不读取EOF和回车 if(check(k,op,a,b))key=0;//读取的是个运算符,说明要接受新数字,将key关闭 else if(k>=48&&k<=57)//如果是数字 if(key)b[++b[0]]=k-48;//如果不是第一次碰到非0就记录 else if(k!=48)b[++b[0]]=k-48,key=1;//第一次碰到非0的数字记录,并且把key打开 } else if(k>=48&&k<=57)//如果是数字 if(key)a[++a[0]]=k-48;//如果不是第一次碰到非0就记录 else if(k!=48)a[++a[0]]=k-48,key=1;//第一次碰到非0的数字记录,并且把key打开 } if(!mark)deal(a);//没处理就处理一下 yunsuan(op,a,b);//最后没有运算符,不会自动进行计算,手动补上一步 out(a);//输出 }
0.0分
2 人评分
分糖果 (C++代码)浏览:933 |
人见人爱A+B (C语言代码)浏览:1046 |
C语言程序设计教程(第三版)课后习题9.6 (C语言代码)浏览:623 |
母牛的故事 (C语言代码)浏览:1409 |
C语言程序设计教程(第三版)课后习题3.7 (C语言代码)浏览:607 |
C语言程序设计教程(第三版)课后习题6.1 (C语言代码)浏览:545 |
C语言程序设计教程(第三版)课后习题11.1 (C语言代码)浏览:686 |
买不到的数目 (C++代码)浏览:909 |
回文串 (C语言代码)浏览:3095 |
C语言程序设计教程(第三版)课后习题6.7 (C语言代码)浏览:548 |