NYOJ513 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

题意:两个数相加,求最后的结果,转化为最简形式。
分析:题目挺坑,没有说具体的输入的两个数的情况,所以只能自己去判断了。
先来说一下这几种情况
0000001 1
.1 1
1. 1
对于以上的情况都要考虑,不然就会错。
由于输入数据带小数,所以难点就在于把整数部分和小数部分分离,还有就是进位。
1.先来看整数部分:顾名思义,就是小数点前面的,分离出来后进行大数加法就可以了,这一部分相对来说简单。
2.小数部分:分离出来后,需要判断两个的长度是否相等(由于用字符串处理的时候小数部分是从后往前加),
如果不相等的话,就会发现加的位置错误,例如(0.123456789 0.1)。
3.还有一个,就是小数部分向大数的进位,如果有进位的话,需要用之前计算过的大数加上进位。
另附一组输入数据
12345.6789 1.1001
12345.6789 0.4321
12345.6789 0.4567
0 0
0.0 0.1
0.0 0.0
1.0 1.
1.0 .1
1.9 0.1
0.1 0.9
1.23 2.1
3 4.0
0.123456789 0.987654321
25 15
0 0
0.123 0.123
0.123 0.9
0.999 0.001
000001 1

</pre><pre name="code" class="html">#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <algorithm>
using namespace std;
///a.size() >= b.size()
string fun(string a,string b)
{
    string e = "";
    int num = 0;
    int sum = 0;
    int len_a = a.size();
    int len_b = b.size();
    while(num < len_a)
    {
        sum += a[num] - '0' + b[num] - '0';
        e += sum % 10 + '0';
        sum /= 10;
        ++ num;
    }
    while(num < len_b)
    {
        sum += b[num] - '0';
        e += sum % 10 + '0';
        sum /= 10;
        ++ num;
    }
    while(sum)
    {
        e += sum % 10 + '0';
        sum /= 10;
    }
    return e;
}
string a,b,c,d,s,str;
///初始化
inline void Init()
{
    a.clear();
    b.clear();
    c.clear();
    d.clear();
}
int main()
{
//    freopen("in.txt","r",stdin);
    int i;
    while(cin >> s >> str)
    {
        Init();
        ///a存储的是整数部分,b存储的是小数部分
        ///把s数组的值给提取出来后,s数组已经没用,可用于接下来的计算
        ///下同
        for(i = 0; i < s.size(); i ++)
            if(s[i] != '.')
                a += s[i];
            else
                break;
        for(++ i; i < s.size(); i ++)
            b += s[i];

        for(i = 0; i < str.size(); i ++)
            if(str[i] != '.')
                c += str[i];
            else
                break;
        for(++ i; i < str.size(); i ++)
            d += str[i];

        ///整数部分的加法,注意长度
        reverse(a.begin(),a.end());
        reverse(c.begin(),c.end());
        ///s求出来后不要反转,后面还有可能会和进位相加
        if(a.size() < c.size())
            s = fun(a,c);
        else
            s = fun(c,a);

        ///如果小数部分位数不等,要把它变成相等
        if(b.size() != d.size())
        {
            if(b.size() > d.size())
            {
                for(i = 0; ; i ++)
                {
                    if(b.size() == d.size())
                        break;
                    else
                        d += "0";
                }
            }
            else
            {
                for(i = 0; ; i ++)
                {
                    if(b.size() == d.size())
                        break;
                    else
                        b += "0";
                }
            }
        }
        ///反转,从低位到高位相加
        reverse(b.begin(),b.end());
        reverse(d.begin(),d.end());
        str = fun(b,d);///b和d长度相同
        reverse(str.begin(),str.end());
        ///有进位
        if(str.size() > b.size())
        {
            ///把进位放入f字符串中
            string f = "";
            f = str[0];
            ///有进位,所以把进位提取出来
            if(s.size() < f.size())
                s = fun(s,f);
            else
                s = fun(f,s);
            reverse(s.begin(),s.end());
            ///去除前导0,例如000001
            bool flag = 0;
            for(i = 0; i < s.size(); i ++)
                if(s[i] != '0')
                    break;
            for(i; i < s.size(); i ++)
            {
                cout << s[i];
                flag = 1;
            }
            if(!flag)
                cout << 0;
            ///注意,因为有进位,所以第0位不考虑
            for(i = str.size() - 1; i >= 1; i --)
            {
                if(str[i] != '0')
                    break;
            }
            s.clear();
            for(i; i >= 1; i --)
                s += str[i];
            if(s.size() > 0)
            {
                reverse(s.begin(),s.end());
                cout << '.' << s << endl;
            }
            else
                cout << endl;
        }
        else
        {
            reverse(s.begin(),s.end());
            bool flag = 0;
            for(i = 0; i < s.size(); i ++)
                if(s[i] != '0')
                    break;
            for(i; i < s.size(); i ++)
            {
                flag = 1;
                cout << s[i];
            }
            if(!flag)
                cout << 0;
            for(i = str.size() - 1; i >= 0; i --)
            {
                if(str[i] != '0')
                    break;
            }
            s.clear();
            for(i; i >= 0; i --)
                s += str[i];
            if(s.size() > 0)
            {
                reverse(s.begin(),s.end());
                cout << '.' << s << endl;
            }
            else
                cout << endl;
        }
    }
    return 0;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值