字符串大数相加:从初稿到优化的思路演进
字符串大数相加:从初稿到优化的思路演进
在面试中,经常会遇到这样一道经典题目:
给定两个字符串形式的非负整数
num1
和num2
,返回它们的和(结果也要用字符串表示)。
要求:不能使用BigInteger
,也不能直接将字符串转成数字类型。
例如:
- 输入:
num1 = "123"
,num2 = "456"
- 输出:
"579"
核心还是模拟竖式加法,但实现上更「稳健」:
- 使用两个指针
i
、j
从尾部往前遍历; - 每一位取值时注意下标是否越界,不够的补 0;
- 每一轮相加时都加上
carry
; - 当前结果 =
(x + y + carry) % 10
,新的进位 =(x + y + carry) / 10
,这是进位计算比较快的方式,也可以用单独的变量处理进位,但相对会麻烦一些; - 最后别忘了反转字符串,因为刚开始添加是从后到前的。
3. 最终代码
public class AddStrings {public static String addStrings(String num1, String num2) {int i = num1.length() - 1;int j = num2.length() - 1;int carry = 0; // 进位StringBuilder sb = new StringBuilder();while (i >= 0 || j >= 0 || carry > 0) {// 平常用不到可能注意不到,所以写完需要测试下,顺手直接写成(int)num1.charAt(i--)结果是错误的int x = (i >= 0) ? num1.charAt(i--) - '0' : 0;int y = (j >= 0) ? num2.charAt(j--) - '0' : 0;int sum = x + y + carry;sb.append(sum % 10); // 当前位carry = sum / 10; // 更新进位}return sb.reverse().toString();}public static void main(String[] args) {System.out.println(addStrings("123", "456")); // 579System.out.println(addStrings("99", "9")); // 108System.out.println(addStrings("0", "0")); // 0}
}
注:字符与数字的区别
在字符串加法中,最容易犯的错误就是直接把字符 (char)
转换成整型 (int)
。
-
char
类型存储的是 字符的编码值(ASCII/Unicode),而不是数字本身。 -
例如:
System.out.println((int)'3'); // 输出 51 System.out.println('3' - '0'); // 输出 3
-
因此,正确的做法是用
'c' - '0'
将字符'0' ~ '9'
转换为对应的 整数 0 ~ 9。
✅ 总结:思路没问题,细节要打磨。面试官更看重你发现问题、改进问题的能力。