NYOJ A+B Problem IV 高精度正实数加法

A+B Problem IV
时间限制:1000 ms | 内存限制:65535 KB
难度:3
描述
acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这个问题给解决了。
输入
包含多组测试数据
每组数据包含两个正数A,B(可能为小数且位数不大于400)
输出
每组输出数据占一行,输出A+B的结果,结果需要是最简的形式。
样例输入
1.9 0.1
0.1 0.9
1.23 2.1
3 4.0
样例输出
2
1
3.33
7

高精度的正实数大数加法,需要考虑的东西很多,加油,200块之路。


#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define MOD 1000000007
#define fir first
#define sec second
#define fin freopen("/home/ostreambaba/文档/input.txt", "r", stdin)
#define fout freopen("/home/ostreambaba/文档/output.txt", "w", stdout)
#define mes(x, m) memset(x, m, sizeof(x))
#define Pii pair
#define Pll pair
#define INF 1e9+7
#define Pi 4.0*atan(1.0)
#define lowbit(x) (x&-x)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
typedef long long ll;
typedef unsigned long long ull;
const double eps = 1e-7;
const int MAX = 101;
using namespace std;
#define time
bool isZero(const string str)   //判断小数部分字符串是否都为0
{
    int num;
    sscanf(str.c_str(), "%d", &num);
    if(0 == num){
        return true;
    }
    return false;
}
int main()
{
    string s1, s2, s3, s4;  //s1,s2代表整数部分, s3,s4代表小数部分
    while(cin >> s1 >> s2){
        int pos, flag = 0; //flag表示小数部分相加是否会大于等于1,大于则flag = 1, pos代表小数点的位置
        pos = s1.find(".");
        s3 = s1.substr(pos+1, s1.size());  //提取小数点部分
        s1 = s1.substr(0, pos); 
        if(pos == -1){ //若没有小数点部分,则直接赋值为0
            s3 = "0";
        }
        pos = s2.find("."); //同上
        s4 = s2.substr(pos+1, s2.size());
        if(pos == -1){
            s4 = "0";
        }
        s2 = s2.substr(0, pos);
        int mlen = min(s3.size(), s4.size());  //小数部分相加
        if(s3.size() < s4.size()){  //以长度较长的字符串作为标准
            string tmp = s3;
            s3 = s4;
            s4 = tmp;
        }
        if(s1.size() < s2.size()){ //同上
            string tmp = s1;
            s1 = s2;
            s2 = tmp;
        }
        for(int i = mlen - 1; i >= 0; --i){  //小数部分相加
            s3[i] += s4[i] - '0';
            if(s3[i] > '9'){  
                if(i == 0){   //当最大的位置相加大于9
                    s3[i] -= 10;
                    flag = 1;//则整数部分+1
                    break; 
                }
                s3[i] -= 10;   //不是最大位置则进行进行加法 
                s3[i-1] += 1;  //进位
            }
        }
        int minlen = min(s1.size(), s2.size());   //整数部分相加,从s1,s2尾部开始相加,maxlen代表较长的字符串, minlen代表较短的字符串
        int maxlen = max(s1.size(), s2.size());
        string str = "1";  //整数部分最大位置大于9 则 +1
        for(int i = minlen - 1, j = maxlen - 1; i >= 0; --i, --j){  //字符串相加
            s1[j] += s2[i] - '0';
            if(s1[j] > '9'){     // 大于9,分情况
                if(i == 0 && j == 0){   // 两字符串长度恰好相同, 如9+1=10
                    if(s1[j] > '9'){    //因为怕越界,所以直接s1之前加1  
                        s1[j] -= 10;
                        s1 = str + s1;  // 1+XXXX
                        break; 
                    }
                }
                else if(i == 0 && j != 0){  //两长度不一样,一样的步骤
                      s1[j] -= 10;
                      s1[j-1] += 1;
                      for(int k = j-1; k >= 0; --k){
                           if(s1[k] > '9'){
                             if(k == 0){  // 这里就考虑到  999+1 = 10000,思想同上
                                 s1[k] -= 10;
                                 string str = "1";
                                 s1 = str + s1;
                                 break;
                             }
                             s1[k] -= 10;
                             s1[k-1] += 1;
                        }
                    }
                }
                if(i != 0){   //因为上面if(i==0)那步break跳出循环就不下需要执行了,所以这里要加限定条件, 不然会再执行一次会出错
                    s1[j] -= 10;
                    s1[j-1] += 1;
                }
            }
        }
      // cout << s1 << endl;
        if(flag == 1){  //整数部分+1  和上面差不多, 需要考虑 999+1
            s1[s1.size()-1] += flag;
            if(s1[s1.size()-1] > '9'){
                for(int i = s1.size()-1; i >= 0; --i){
                    if(s1[i] > '9'){
                        if(0 == i){
                            s1[i] -= 10;
                            s1 = str + s1;
                            break;
                        }
                        s1[i] -= 10;
                        s1[i-1] += 1;
                    }
                }
            }
        }
        if(!isZero(s3)){  //判断小数部分是否为0,为0则不输出
            int k = s3.size();
            while(s3[--k] == '0');  //去掉多余的0
            s3 = s3.substr(0, k+1);
            //cout << s3 << endl;
            cout << s1 << "." << s3 << endl;
        }
        else{
            cout << s1 << endl;
        }
    }
    return 0;
}


你可能感兴趣的:(南阳理工OJ,NYOJ)