【题目链接】
OpenJudge NOI 1.13 33:实数加法
OpenJudge NOI 1.13 48:实数加法
【题目考点】
1. 高精度
【解题思路】
解法1:使用数组、函数
将输入的数字根据’.'来分成前后两部分,前面是整数部分,后面是小数部分。
a[i]
表示整数部分小数点前第i位的数字,an为小数点前数字个数。b[i]
表示小数点后第i位的数字,bn为小数点后数字个数。将第1个实数分解成a1,b1两个数组,将第2个实数分解成a2,b2两个数组。
先让b1与b2做高精度加法,相加的末位为b1与b2长度的最大值,从这一位开始不断相加,结果保存在b3,进位为c。
也许末位相加后结果为0,会导致小数点后的位数bn变少。所以只要bn指向的位置为0,就向前移动。
保留进位c,参与整数部分的相加。让a1与a2相加得到a3,得到的结果可能会超出a1与a2的最大长度。
最后输出a3,点,b3。
解法2:写高精度实数类
用类表示一个实数,包含属性:整数部分数字数组a,长度an;小数部分数字数组b,长度bn。解题思路与解法1相同,但用类来写代码更有层次,读起来更清晰。推荐写类来解决问题。
【题解代码】
解法1:使用数组、函数
#include <bits/stdc++.h>
using namespace std;
#define N 105
int getA(char s[], int p, int a[])
{
int an = 0;
for(int i = p-1; i >= 0; --i)
a[++an] = s[i]-'0';
return an;
}
int getB(char s[], int p, int b[])
{
int bn = 0, len = strlen(s);
for(int i = p+1; i < len; ++i)
b[++bn] = s[i]-'0';
return bn;
}
int getP(char s[])
{
int len = strlen(s);
for(int i = 0; i < len; ++i)
if(s[i] == '.')
return i;
}
char s[N];
int a1[N], b1[N], a2[N], b2[N], a3[N], b3[N], an1, an2, an3, bn1, bn2, bn3;
int main()
{
cin >> s;
int p = getP(s);
an1 = getA(s, p, a1);
bn1 = getB(s, p, b1);
cin >> s;
p = getP(s);
an2 = getA(s, p, a2);
bn2 = getB(s, p, b2);
bn3 = max(bn1, bn2);
int c = 0;
for(int i = bn3; i >= 1; --i)
{
b3[i] = b1[i]+b2[i]+c;
c = b3[i]/10;
b3[i] %= 10;
}
while(b3[bn3] == 0)
bn3--;
an3 = max(an1, an2);
for(int i = 1; i <= an3; ++i)
{
a3[i] = a1[i]+a2[i]+c;
c = a3[i]/10;
a3[i] %= 10;
}
if(c > 0)
a3[++an3] = c;
for(int i = an3; i >= 1; --i)
cout << a3[i];
cout << '.';
for(int i = 1; i <= bn3; ++i)
cout << b3[i];
return 0;
}
解法2:写高精度实数类
#include <bits/stdc++.h>
using namespace std;
#define N 105
struct RealNum
{
int a[N], b[N];//a[i]:小数点前第i位 b[i]:小数点后第i位
int an, bn;//an:小数点前有几位 bn:小数点后有几位
RealNum(){}
RealNum(string s)
{
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
an = bn = 0;
int p = 0;
while(s[p] != '.')
p++;
for(int i = p-1; i >= 0; --i)
a[++an] = s[i] - '0';
for(int i = p+1; i < s.length(); ++i)
b[++bn] = s[i] - '0';
}
void operator += (RealNum x)//自己加上x
{
int c = 0;
bn = max(bn, x.bn);
for(int i = bn; i >= 1; --i)
{
b[i] = b[i] + x.b[i] + c;
c = b[i]/10;
b[i] %= 10;
}
while(b[bn] == 0)
bn--;
an = max(an, x.an);
for(int i = 1; i <= an; ++i)
{
a[i] = a[i] + x.a[i] + c;
c = a[i]/10;
a[i] %= 10;
}
if(c > 0)
a[++an] = c;
}
void show()
{
for(int i = an; i >= 1; --i)
cout << a[i];
cout << '.';
for(int i = 1; i <= bn; ++i)
cout << b[i];
}
};
int main()
{
string s1, s2;
cin >> s1 >> s2;
RealNum r1(s1), r2(s2);
r1 += r2;
r1.show();
return 0;
}