[C++]<原创>带符号的大整数相减【新手向】

本人是编程新手,整理出这题我认为最适合新手的思路供参考。

只使用最简单的函数和运算符,便于理解。


题目

题目描述

给定两个不超过200位的大整数(200位包含符号位。正整数和0可以带符号,也可以不带符号),计算其差值(前面的值-后面的值)。

关于输入

第1行输入 n ,表示后面有 n 组数。
之后,每组数依次占两行,表示被减数与减数;相邻的两组数之间隔一行。

关于输出

逐行输出相减的结果(若结果不为0,最高位不能是0;若结果为非负整数,不能带符号)。

例子输入
5
-567123
-545012

121346
-17623

+12341
2346789

-21346
+87623

-0
-9876543210
例子输出
-22111
138969
-2334448
-108969
9876543210
提示信息

结果的最高位不能是 0,除非结果为0

本题来自编程网格 - Programming Grid


My Code

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

// 简单的去除前导0的方式
void clearLeadingZeros(string &s){
    while (s.size() > 1 && s[0] == '0') {
        s.erase(s.begin());
    }
}

// 比较大小函数,保证减法输出正数
bool isLarger(string s1, string s2){
    if (s1.size() > s2.size()) {
        return true;
    }
    if (s1.size() < s2.size()) {
        return false;
    }
    for (int i = 0; i < s1.size(); i++) {
        if (s1[i] > s2[i]) {
            return true;
        }
        if (s1[i] < s2[i]) {
            return false;
        }
    }
    return true;
}

string largeAddition(string s1, string s2){
    if (s1.size() > s2.size()) {
        swap(s1, s2);
    }
    while (s1.size() < s2.size()) {
        s1 = '0' + s1;
    }
    // 我觉得reverse后做运算更便于理解
    reverse(s1.begin(), s1.end());
    reverse(s2.begin(), s2.end());
    string result = "";
    int carry = 0;
    for (int i = 0; i < s1.size(); i++) {
        int temp = (s1[i] - '0') + (s2[i] - '0') + carry;
        carry = temp / 10;
        temp %= 10;
        result.push_back(temp + '0');
    }
    if (carry) {
        result.push_back(carry + '0');
    }
    reverse(result.begin(), result.end());
    clearLeadingZeros(result);
    return result;
}

// 保证了s1大于等于s2
string largeSubtraction(string s1, string s2){
    while (s1.size() > s2.size()) {
        s2 = '0' + s2;
    }
    reverse(s1.begin(), s1.end());
    reverse(s2.begin(), s2.end());
    string result = "";
    int carry = 0;
    for (int i = 0; i < s1.size(); i++) {
        int temp = (s1[i] - '0') - (s2[i] - '0') - carry;
        if (temp < 0) {
            temp += 10;
            carry = 1;
        } else {
            carry = 0;
        }
        result.push_back(temp + '0');
    }
    reverse(result.begin(), result.end());
    clearLeadingZeros(result);
    return result;
}

int main(){
    int n;
    cin >> n;
    string s1, s2;
    for (int i = 0; i < n; i++) {
        cin >> s1 >> s2;
        if (s1[0] == '+') {
            s1 = s1.substr(1);
        }
        if (s2[0] == '+') {
            s2 = s2.substr(1);
        }
        // 处理相同的情况防止输出“-0”
        if (s1 == s2) {
            cout << "0" << endl;
            continue;
        }
        // 一些枚举,可能臃肿但便于理解
        if (s1[0] != '-' && s2[0] == '-') {
            s2 = s2.substr(1);
            cout << largeAddition(s1, s2) << endl;
        } else if (s1[0] == '-' && s2[0] != '-') {
            s1 = s1.substr(1);
            cout << '-' << largeAddition(s1, s2) << endl;
        } else if (s1[0] == '-' && s2[0] == '-') {
            s1 = s1.substr(1);
            s2 = s2.substr(1);
            if (isLarger(s1, s2)) {
                cout << '-' << largeSubtraction(s1, s2) << endl;
            }
            else {
                cout << largeSubtraction(s2, s1) << endl;
            }
        } else {
            if (isLarger(s1, s2)) {
                cout << largeSubtraction(s1, s2) << endl;
            }
            else {
                cout << '-' << largeSubtraction(s2, s1) << endl;
            }
        }
    }
}

随机更新本人编程学习的心得体会~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值