zoukankan      html  css  js  c++  java
  • 实数加法的一个解决思路

    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++有一种排斥感,实际上截取字符串也很简单,但就是感觉别扭。

  • 相关阅读:
    【Linux 读书笔记】Linux文件的硬连接和符号连接
    Shell参数
    Shellcase语句的例子
    Shellselect
    Shell小程序一个
    SHELL起步
    接昨天的 while
    Shell循环控制
    Shellwhile循环的例子
    Shellfor语句
  • 原文地址:https://www.cnblogs.com/zcsor/p/6380177.html
Copyright © 2011-2022 走看看