AcWing 792:高精度减法 ← vector

【题目来源】
https://www.luogu.com.cn/problem/P2142
https://www.acwing.com/problem/content/794/

【题目描述】
给定两个正整数(不含前导 0),计算它们的差,计算结果可能为负数。

【输入格式】
共两行,每行包含一个整数。

【输出格式】
共一行,包含所求的差。

【数据范围】
1≤整数长度≤100000

【输入样例】
32
11

【输出样例】
21

【算法分析】
1.C++不支持大数运算,故而引入高精度算法。
2.高精度减法将大数以字符串形式输入,然后拆分转换为一位一位的整数,之后按照小学的竖式运算方法完成编码。(注意:字符串中0下标从左开始,竖式运算中0下标从右开始,故代码中需要有一个逆序操作。如
a[i]=s1[s1.length()-i-1]-'0';
3.高精度减法中需判断减数、被减数的大小 --> 若s1、s2是string类型,则用
s1.compare(s2) 来判断s1、s2大小。若s1、s2是字符数组,则用 strcmp(s1,s2) 来判断s1、s2大小。当然,也可以自定义函数来进行判断。
4.高精度减法中需交换减数、被减数 --> 若s1、s2是string类型,则再引入一个字符串t,然后用“
t=s1;s1=s2;s2=t;”来完成s1、s2的交换。若s1、s2是字符数组,则再引入一个字符数组t,然后用“strcpy(t,s1);strcpy(s1,s2);strcpy(s2,t);”来完成s1、s2的交换。
5.对最高位做判断,
删除前导0,然后输出便得结果。如需对例子1235-1233=0002进行前导0的删除。

【算法代码一】

#include <bits/stdc++.h>
using namespace std;

bool cmp(vector<int> &A,vector<int> &B) {
    if(A.size()!=B.size()) return A.size()>B.size();
    for(int i=A.size()-1; i>=0; i--) {
        if(A[i]!=B[i]) return A[i]>B[i];
    }
    return true;
}

//C=A-B,满足A>=B,A>=0,B>=0
vector<int> sub(vector<int> &A, vector<int> &B) {
    vector<int> C;
    for(int i=0,t=0; i<A.size(); i++) {
        t=A[i]-t;
        if(i<B.size()) t-=B[i];
        C.push_back((t+10)%10);
        if(t<0) t=1;
        else t=0;
    }

    while(C.size()>1 && C.back()==0) C.pop_back();
    return C;
}

int main() {
    string a,b;
    vector<int> A,B;
    cin>>a>>b;
    for(int i=a.size()-1; i>=0; i--) A.push_back(a[i]-'0');
    for(int i=b.size()-1; i>=0; i--) B.push_back(b[i]-'0');
    if(cmp(A,B)) {
        auto C=sub(A,B);
        for(int i=C.size()-1; i>=0; i--) printf("%d",C[i]);
    } else {
        auto C=sub(B,A);
        printf("-");
        for(int i=C.size()-1; i>=0; i--) printf("%d",C[i]);
    }
    return 0;
}


/*
input:
32
11

output:
21
*/


【算法代码二:来源于AcWing 792. 高精度减法 - AcWing

#include <iostream>
#include <vector>
using namespace std;

const int N = 1000010;

bool cmp(vector<int> &A, vector<int> &B) {
	if (A.size() != B.size()) return A.size() >= B.size();
	for (int i = A.size() - 1; i >= 0; i--)
		if (A[i] != B[i])
			return A[i] > B[i];
	return true;
}

void trimZero(vector<int> &A) {
	while (A.back() == 0 && A.size() > 1) A.pop_back();
}

vector<int> sub(vector<int> &A, vector<int> &B) {
	vector<int> C;
	int t = 0;
	for (int i = 0; i < A.size(); i++) {
		t = A[i] - t;
		if (i < B.size()) t -= B[i];
		C.push_back((t + 10) % 10);
		if (t < 0) t = 1;
		else t = 0;
	}
	trimZero(C);

	return C;
}

int main() {
	string a, b;
	cin >> a >> b;
	vector<int> A, B, C;
	for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
	for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');

	trimZero(A), trimZero(B);

	if (cmp(A, B)) C = sub(A, B);
	else {
		C = sub(B, A);
		printf("-");
	}
	for (int i = C.size() - 1; i >= 0; i--) cout << C[i];

	return 0;
}


/*
input:
56328123678
958729125679
output:
-902401002001
-----------------------
input:
9876543219
123456789
output:
9753086430
*/


【参考文献】
https://www.acwing.com/blog/content/277/
https://www.runoob.com/cplusplus/cpp-strings.html
https://blog.csdn.net/qq_37941471/article/details/82107077
https://blog.csdn.net/justidle/article/details/104426323
 

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值