P2142 高精度减法
题目
高精度减法。
输入
两个整数 \(a,b\)(第二个可能比第一个大)。
输出
结果(是负数要输出负号)。
样例
输入
2
1
输出
1
提示
- \(20\%\) 数据 \(a,b\) 在 long long 范围内;
- \(100\%\) 数据 \(0<a,b\le 10^{10086}\)。
思路
根据题意,数据最大范围是 \(10^{10086}\),需要使用高精度算法。高精度数读取与存储的方式借鉴高精度加法,所不同的是在减法运算中需要考虑减数与被减数的大小,以确定差的正负。但高精度减法依然借助数组 a
存储转换后的被减数,数组 b
存储转换后的减数。
如果被减数比减数大,直接根据竖式减法运算规则进行运算。枚举被减数与减数的对应位分别为 \(a_i\) 和 \(b_i\) 进行相减后赋值给 \(c_i\),如果 \(a_i\) 小于 \(b_i\),则向 \(a_{i+1}\) 进行借位操作,之后再进行相减。最后从高位向低位输出 \(c_i\)。
if (a[i] < b[i])
{
a[i] += 10;
a[i + 1] --;
}
c[i] = a[i] - b[i];
经过判断如果被减数比减数小,则进行字符串交换,并标记差的符号。字符串比较中,字符串长度大的对应高精度数值较大,如果字符串长度相等,则直接运行字符串函数进行比较。
if (strlen(a1) < strlen(b1) || (strlen(a1) == strlen(b1) && strcmp(a1, b1) < 0))
{
strcpy(temp, a1);
strcpy(a1, b1);
strcpy(b1, temp);
f = '-'; // 记录差的正负
}
代码一:数组
#include <bits/stdc++.h>
using namespace std;
int a[10100], b[10100], c[10100], lena, lenb, lenc;
char a1[10100], b1[10100], temp[10100], f;
int main()
{
cin >> a1 >> b1;
// 判断减数与被减数的大小
if (strlen(a1) < strlen(b1) || (strlen(a1) == strlen(b1) && strcmp(a1, b1) < 0))
{
strcpy(temp, a1);
strcpy(a1, b1);
strcpy(b1, temp);
f = '-'; // 记录差的正负
}
lena = strlen(a1);
lenb = strlen(b1);
for (int i = 0; i <= lena - 1; i ++ )
a[lena - i] = a1[i] - 48;
for (int i = 0; i <= lenb - 1; i ++ )
b[lenb - i] = b1[i] - 48;
lenc = lena;
for (int i = 1; i <= lenc; i ++ )
{
if (a[i] < b[i])
{
a[i] += 10;
a[i + 1] --;
}
c[i] = a[i] - b[i];
}
// 去掉前导 0
while (c[lenc] == 0 && lenc > 1)
lenc --;
if (f == '-')
cout << '-';
for (int i = lenc; i >= 1; i -- )
cout << c[i];
return 0;
}
代码二:重载运算符
以上代码可以进行空间优化,c
数组可以省略,将差直接存储到 a
数组中。
运用结构体重载运算符的方式也可以得到高精度减法的另一种写法。
#include <bits/stdc++.h>
using namespace std;
char str[10100];
struct node
{
int len, s[10100];
node()
{
len = 0;
memset(s, 0, sizeof(s));
}
};
bool operator >= (const node &a, const node &b) // 判断大小
{
if (a.len < b.len)
return 0;
if (a.len == b.len)
{
for (int i = 1; i <= b.len; i ++ )
{
if (a.s[i] > b.s[i])
return 1;
else if (a.s[i] < b.s[i])
return 0;
}
}
return 1;
}
node operator - (node &a, const node &b)
{
node c;
c.len = max(a.len, b.len);
for (int i = 1; i <= c.len; i ++ )
{
c.s[i] = a.s[i] - b.s[i];
if (c.s[i] < 0)
{
c.s[i] += 10;
a.s[i + 1] --;
}
}
while (c.len > 0 && !c.s[c.len])
c.len --;
if (c.len == 0)
{
c.len = 1;
c.s[1] = 0;
}
return c;
}
node read()
{
scanf("%s", str);
int len = strlen(str);
node a;
a.len = len;
for (int i = 0; i < len; i ++ )
a.s[len - i] = str[i] - '0';
return a;
}
void print(node a)
{
for (int i = a.len; i >= 1; i -- )
printf("%d", a.s[i]);
}
int main()
{
node a, b, c;
a = read();
b = read();
if (a >= b)
c = a - b;
else
{
c = b - a;
putchar('-');
}
print(c);
return 0;
}
标签:node,P2142,高精度,int,len,a1,b1,减法,strlen
From: https://www.cnblogs.com/IronMan-PZX/p/18132778