假设两个非负高精度整数分别存储在数组 a 和 b 中,且 $a \ge b$。数组采用低位在前的方式存储,即 a[0] 表示个位。下面代码中的 c 可以正确保存 a - b 的各位数字。
int borrow = 0;
for (int i = 0; i < len; ++i) {
int t = a[i] - b[i] + borrow;
if (t < 0) {
t += 10;
borrow = 1;
} else {
borrow = 0;
}
c[i] = t;
}看到减法循环先想"借位传播是否正确"。本题陷阱在于代码假设 a 和 b 长度相同,却未处理 a 比 b 短的情况。当 a 位数不足时,高位 b[i] 会直接参与减法,导致结果错误。正确做法应比较长度,不足位补 0 或提前终止。
选项 A 看似逻辑通顺,实则忽略了"a 比 b 短"的边界。命题人故意用相同长度数组误导考生,而真实考题中 a,b 长度可不同。若 a 短于 b,循环中 a[i] 越界,t 计算错误,最终 c 数组存满错误数字。
考纲定位:GESP 五级《算法设计》模块,考察高精度减法与数组边界处理。命题人卡住的是"默认长度相同"的惯性思维,绝大多数考生会忽略 a 比 b 短的情形。
解题思维:看到减法循环先想"借位传播是否正确"。本题陷阱在于代码假设 a 和 b 长度相同,却未处理 a 比 b 短的情况。当 a 位数不足时,高位 b[i] 会直接参与减法,导致结果错误。正确做法应比较长度,不足位补 0 或提前终止。
陷阱拆解:选项 A 看似逻辑通顺,实则忽略了"a 比 b 短"的边界。命题人故意用相同长度数组误导考生,而真实考题中 a,b 长度可不同。若 a 短于 b,循环中 a[i] 越界,t 计算错误,最终 c 数组存满错误数字。
反命题思维:若把条件改为"a 和 b 长度相同",答案变 A;若改为"a 比 b 短",答案变 B;若改为"a 比 b 长",答案变 A。命题人正是利用考生对"长度相同"的默认假设,埋下越界陷阱。
例如 a=[3,2,1] (123), b=[4,5] (45)。循环 i=0 时 t=3-4+0=-1→9,borrow=1;i=1 时 t=2-5+1=-2→8,borrow=1;i=2 时 t=1-0+1=2,borrow=0。c=[9,8,2] 即 289,而 123-45=78,明显错误。
这类题通法:先比较长度,短者高位补 0,再逐位相减并处理借位。若 a 比 b 短,循环应只到 min(len_a, len_b),剩余高位直接复制 b 的对应位(或先整体减再补 0)。