字符串相减(大数相减)
约 483 字大约 2 分钟
2025-03-01
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的差。
注意:
- num1 和num2 都只会包含数字 0-9
- num1 和num2 都不包含任何前导零
- 你不能使用任何內建 BigInteger 库
('0' + val)
将这个整数值转换为对应的字符形式。例如:
val = 0
时,'0' + 0 = '0'
val = 1
时,'0' + 1 = '1'
val = 9
时,'0' + 9 = '9'
这是因为 ASCII 码中,字符 '0'
的值是 48,字符 '1'
是 49,依此类推。
(char) ('0' + val)
将 int
类型的结果强制转换为 char
类型,使其成为一个字符。
class Solution {
// 执行基数为10的减法运算
public static String sub(String a, String b) {
StringBuilder res = new StringBuilder();
int borrow = 0;
int i = a.length() - 1, j = b.length() - 1;
// 逐位计算减法
// 对于加法,结束条件还要加一个进位不为零
while (i >= 0 || j >= 0) {
int x = i >= 0 ? a.charAt(i) - '0' : 0;
int y = j >= 0 ? b.charAt(j) - '0' : 0;
// 重点。
int val = (x - borrow - y + 10) % 10;
// 注意必须要+'0',假设val=2,'0'的ASCII值是48,我们要计算ASCII值,然后转成字符。
res.append((char) ('0' + val));
// 重点。
borrow = x - borrow - y < 0 ? 1 : 0;
i--;
j--;
}
// 反转结果字符串
res.reverse();
// 删除前导零。循环条件是 res.length() - 1 是为防止 "0000" 的情况。只需检查[0,res.length-2],不需要检查最后一个是否为零,就是它是零也无所谓。
int pos;
for (pos = 0; pos < res.length() - 1; pos++) {
if (res.charAt(pos) != '0') break;
}
return res.substring(pos);
}
// 比较两个字符串大小
public static boolean cmp(String a, String b) {
if (a.length() == b.length()) return a.compareTo(b) < 0;
return a.length() < b.length();
}
// 执行两个基数为10的字符串的减法运算
public static String subStrings(String num1, String num2) {
String res;
// 如果nums1<num2,则先用num2减去num1,再在结果前加个负号。
if (cmp(num1, num2)) {
res = sub(num2, num1);
// 重点。
if (!res.equals("0")) res = "-" + res;
} else {
res = sub(num1, num2);
}
return res;
}
}