题目
任意大小的两个十进制正整数(字符串表示)相减,输出结果
解答
这里因为是任意大小(当然计算机也是有限制的),所以并不能采用基本类型进行计算,当然我们也不考虑采用大数类(如 Java 的 BigInteger)
我们依旧采用竖式计算,但是在处理的时候,应该注意几个处理点
- 较大的数减去较小的数,方便竖式计算;符号通过是否较大数在前判定;
- 当对应位的数值不足,应该从较大数前一位退位,补足,然后再相减(如 11 - 2 = 9,1 - 2 不足,10 退位补足,计算 11 - 2 = 9)
#include <iostream>
#include <string>
using namespace std;
int char2int(char c) {
return c - '0';
}
char int2char(int i) {
return i + '0';
}
// 计算符号,判断较大数
void get_calc_factor(const string& num1, const string& num2,
string& fst, string& sec, int& plus) {
plus = 1;
int i = 0;
if (num1.length() < num2.length()) {
plus = 0;
} else if (num1.length() == num2.length()) {
while (i < num1.length()) {
if (num1[i] < num2[i]) {
plus = 0;
break;
} else if (num1[i] > num2[i]) {
plus = 1;
break;
}
i++;
}
}
if (plus == 0) {
fst = num2;
sec = num1;
} else {
fst = num1;
sec = num2;
}
}
string big_numbers_minus(const string& num1, const string& num2, int plus) {
const int BASE = 10;
size_t len1 = num1.length();
size_t len2 = num2.length();
size_t len_max = len1; // num1 > num2
char* dst = new char[len_max + 1];
dst[len_max] = '\0';
int i = len1 - 1;
int j = len2 - 1;
int k = len_max - 1;
int down = 0;
while (i >= 0 && j >= 0) {
if (num1[i] - num2[j] + down < 0) {
dst[k] = int2char(num1[i] + BASE - num2[j] + down);
down = -1;
} else {
dst[k] = int2char(num1[i] - num2[j] + down);
down = 0;
}
i--;
j--;
k--;
}
while (i >= 0) {
if (char2int(num1[i] + down) < 0) {
dst[k] = num1[i] + BASE + down;
down = -1;
} else {
dst[k] = num1[i] + down;
}
i--;
k--;
}
string res(dst);
while (res[0] == '0' && res.length() > 1) {
res.erase(0, 1); // 移除前面的 0
}
if (plus == 0) {
res = "-" + res;
}
delete[] dst;
dst = NULL;
return res;
}
int main() {
string num1, num2;
while (std::cin >> num1 >> num2) {
string fst, sec, res;
int plus;
get_calc_factor(num1, num2, fst, sec, plus);
res = big_numbers_minus(fst, sec, plus);
std::cout << res << std::endl;
}
return 0;
}
运行结果
1 2
-1
10 20
-10
20 10
10
123 223
-100
1324654654687987 4968789789798789746546
-4968788465144135058559
13546578676 12121456144
1425122532