leetcode-master/problems/kamacoder/0121.大数减法.md

2.6 KiB
Raw Blame History

参与本项目,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们受益!

大数减法

本题测试数据超过int 和 longlong了所以考察的使用 string 来模拟 两个大数的 加减操作。

当然如果使用python或者Java 使用库函数都可以水过。

使用字符串来模拟过程,需要处理以下几个问题:

  • 负号处理:要考虑正负数的处理,如果大数相减的结果是负数,需要在结果前加上负号。
  • 大数比较:在进行减法之前,需要确定哪个数大,以便知道结果是否需要添加负号。
  • 位数借位:处理大数相减时的借位问题,这类似于手动减法。
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

// 比较两个字符串表示的数字返回1表示a > b0表示a == b-1表示a < b
int compareStrings(const string& a, const string& b) {
    if (a.length() > b.length()) return 1;
    if (a.length() < b.length()) return -1;
    return a.compare(b);
}

// 去除字符串左侧的前导零
string removeLeadingZeros(const string& num) {
    size_t start = 0;
    while (start < num.size() && num[start] == '0') {
        start++;
    }
    return start == num.size() ? "0" : num.substr(start);
}

// 大数相减假设a >= b
string subtractStrings(const string& a, const string& b) {
    string result;
    int len1 = a.length(), len2 = b.length();
    int carry = 0;

    for (int i = 0; i < len1; i++) {
        int digitA = a[len1 - 1 - i] - '0';
        int digitB = i < len2 ? b[len2 - 1 - i] - '0' : 0;

        int digit = digitA - digitB - carry;
        if (digit < 0) {
            digit += 10;
            carry = 1;
        } else {
            carry = 0;
        }

        result.push_back(digit + '0');
    }

    // 去除结果中的前导零
    reverse(result.begin(), result.end());
    return removeLeadingZeros(result);
}

string subtractLargeNumbers(const string& num1, const string& num2) {
    string a = num1, b = num2;

    // 比较两个数的大小
    int cmp = compareStrings(a, b);

    if (cmp == 0) {
        return "0"; // 如果两个数相等结果为0
    } else if (cmp < 0) {
        // 如果a < b交换它们并在结果前加上负号
        swap(a, b);
        return "-" + subtractStrings(a, b);
    } else {
        return subtractStrings(a, b);
    }
}

int main() {
    string num1, num2;
    cin >> num1 >> num2;

    string result = subtractLargeNumbers(num1, num2);
    cout << result << endl;

    return 0;
}