P2142 高精度减法

P2142 高精度减法

题目

高精度减法。

输入

两个整数 a,b(第二个可能比第一个大)。

输出

结果(是负数要输出负号)。

样例

输入

2
1

输出

1

提示

  • 20% 数据 a,b 在 long long 范围内;
  • 100% 数据 0<a,b1010086

思路

根据题意,数据最大范围是 1010086,需要使用高精度算法。高精度数读取与存储的方式借鉴高精度加法,所不同的是在减法运算中需要考虑减数与被减数的大小,以确定差的正负。但高精度减法依然借助数组 a 存储转换后的被减数,数组 b 存储转换后的减数。

如果被减数比减数大,直接根据竖式减法运算规则进行运算。枚举被减数与减数的对应位分别为 aibi 进行相减后赋值给 ci,如果 ai 小于 bi,则向 ai+1 进行借位操作,之后再进行相减。最后从高位向低位输出 ci

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;
}
posted @   IronMan_PZX  阅读(74)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
Title
点击右上角即可分享
微信分享提示