FreePascal验证含1-9所有数字的程序仅对特定输入有效求助
问题分析与修复方案
核心错误原因
两个程序的共同问题是在循环中直接修改了原始输入的n值,导致后续检查数字时,n已经被截断为空或只剩前半部分,无法完整遍历所有数字。
比如输入123456789,第一次检查i=1时,循环会持续将n除以10直到找到1,此时n已经变为0;后续检查i=2到i=9时,n是0,根本找不到对应数字,所以e永远达不到9,只会输出no。只有输入987654321时,每个i刚好能在当前n的末尾找到,n会被逐步截断为对应前序数字,才能输出yes。
修复后的程序示例
方案1:保留原始输入副本
每次检查数字前,使用原始n的副本遍历,避免修改原始值。修改后的verify1:
program verify1 ; Uses Wincrt ; Var original_n, n, i, r, e : Longint; Begin Readln(original_n); e := 0; For i:=1 To 9 Do Begin n := original_n; // 每次检查前恢复原始值的副本 Repeat r := n Mod 10 ; n := n Div 10 ; Until (r=i) Or (n=0); If (r=i) Then e := e+1 ; End; If e=9 Then Writeln ('yes') Else Writeln ('no'); End.
方案2:用布尔数组标记已出现数字
更高效的方式是用数组记录每个数字的出现状态,仅遍历一次输入即可完成检查:
program verify_fixed ; Uses Wincrt ; Var n, r : Longint; seen: array[1..9] of Boolean; all_found: Boolean; Begin Readln(n); // 初始化数组为未标记状态 for r := 1 to 9 do seen[r] := False; // 遍历数字所有位,标记出现过的数字 while n > 0 do begin r := n Mod 10; if (r >=1) and (r <=9) then seen[r] := True; n := n Div 10; end; // 检查是否1-9所有数字都已出现 all_found := True; for r := 1 to 9 do if not seen[r] then begin all_found := False; break; end; if all_found then Writeln('yes') else Writeln('no'); End.
修复说明
- 方案1针对原代码的核心问题,通过保留原始输入副本,让每次检查
i时都能完整遍历整个数字的所有位。 - 方案2逻辑更清晰高效,仅遍历数字一次就完成标记与检查,避免了重复遍历的冗余操作,也降低了出错概率。
内容的提问来源于stack exchange,提问作者rayyya
相关产品推荐
相关产品推荐

