实数加法的一个解决思路
Posted zcsor
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实数加法的一个解决思路相关的知识,希望对你有一定的参考价值。
33:实数加法 查看 提交 统计 提问 总时间限制: 1000ms 内存限制: 65536kB 描述 求2个实数相加的和。 输入输出中出现的实数都有如下的形式: P1P2...Pi.Q1Q2...Qj。对于整数部分,P1P2...Pi是一个非负整数;对于小数部分,至少有一位且最后一位Qj不等于0。 输入 2行,分别是两个加数。每个加数不超过100个字符。 输出 一行输出是相应的和。数据保证一定是一个小数部分不为0的实数。 样例输入 0.111111111111111111111111111111 0.111111111111111111111111111111 样例输出 0.222222222222222222222222222222
这个问题交了好几次,漏打了一个按址传递,漏了一种情况。简要分析一下,这个题的要点就是:
1、小数点对齐
2、结尾0的处理
结尾0的处理这里开始漏了一种情况,只考虑了小数点之后的不要了,小数点之前的占位0没考虑。例如:1.2+8.8这样。小数点对齐倒是没什么问题,但是处理整数部分对齐的时候忘了一个&,调试半天。这个题最开始的思路是想从小数点开始,分别向左右取4位,保存到int[],然后对齐处理,发现挺烦人的,于是直接在字符串上处理:
1、获取小数点左右两部分,把右边较短的用0右补齐,把左边较短的用0左补齐。
2、从最低位开始逐个字符计算结果和进位,舍弃结尾0。(这里疏漏了,小数点之前的0不能舍弃)。
3、最高位计算之后如果有进位,在左侧添加一位。
4、插入小数点。
5、输出。
这种在字符串上直接处理的做法效率较低,如果时间比较少计算量比较大,那么一定要用int[]数组,一般可以采用万进制。但是这个题完全可以这样做,就像那个除以13的问题一样,都可以直接处理。
#include<iostream> #include<cstring> using namespace std; inline void zx(string v,string &z,string &x){ //分离整数和小数部分 int i; i=v.find("."); z=v.substr(0,i); x=v.substr(i+1,v.size()-1); } inline void xadd(string &x1,string &x2){ //将小数部分较短的填充0以对齐 if(x1.size()>x2.size()){ x2+=string(x1.size()-x2.size(),‘0‘); }else{ x1+=string(x2.size()-x1.size(),‘0‘); } } inline void zadd(string &z1,string &z2){ //将整数部分较短的填充0以对齐 if(z1.size()>z2.size()){ z2=string(z1.size()-z2.size(),‘0‘)+z2; }else{ z1=string(z2.size()-z1.size(),‘0‘)+z1; } } int main(){ string s1,s2,z1,x1,z2,x2,result; cin>>s1>>s2; zx(s1,z1,x1); //整体思路就是按小数点对齐,两侧短的用0补充。这样就可以从低位一直计算到高位。 zx(s2,z2,x2); zadd(z1,z2); xadd(x1,x2); s1=z1+x1; //此时的s1,s2完全对齐,算法可以得到简化。 s2=z2+x2; int i,cur,up=0,rightzeroflag=1; for(i=int(s1.size())-1;i>=0;i--){ cur=s1[i]-‘0‘+s2[i]-‘0‘+up; //当前位的总和 if(i<int(z1.size())){ //小数点后面的不计入,但是过了小数点就需要占位了。 rightzeroflag=0; } if(cur%10==0 && rightzeroflag==1){ //末尾多余的0不计入。 }else{ rightzeroflag=0; result=char(cur%10+‘0‘)+result; //计入当前位的值 } up=cur/10; } cur=z1.size(); //整数部分的大小,确定小数点位置。 if(up!=0){ //如果最高位计算之后需要进位 result=char(up+‘0‘)+result; cur++; } if(cur<int(result.size())){ //如果整数部分大小比返回值小,说明有小数部分。 result.insert(cur,"."); } cout<<result<<endl; }
这个代码好处就在于不用考虑多少位,怎么对齐的问题。还是对C++有一种排斥感,实际上截取字符串也很简单,但就是感觉别扭。
以上是关于实数加法的一个解决思路的主要内容,如果未能解决你的问题,请参考以下文章