Online Compiler C

#include <stdio.h> int main() { int arr[20], cnt=0; int n,i,a,b,max; scanf("%d",&n); int num=n; while(num>0) { arr[cnt]=num%10; num=num/10; cnt++; } for(i=0;i<cnt/2;i++) { b=arr[i]; arr[i]=arr[cnt-1-i]; arr[cnt-1-i]=b; } for(i=0;i<cnt;i++) { max=-1; for(a=i+1;a<cnt;a++) { if(arr[a]>arr[i]) { max=a; } } if(max!=-1) { b=arr[i]; arr[i]=arr[max]; arr[max]=b; break; } } for(i=0;i<cnt;i++) printf("%d", arr[i]); return 0; }
这段代码的功能是:将一个整数 n 的各位数字提取到数组中,然后尝试找到并执行一次交换,使得交换后的数字比原数字大,最后输出交换后的结果。但代码中存在逻辑错误,导致结果可能不正确。

- 在寻找要交换的数字时,内层循环 `for(a=i+1;a<cnt;a++)` 会不断更新 `max` 的值,最终 `max` 记录的是最后一个比 `arr[i]` 大的数字的位置,而不是最右边的最小的大数。这会导致交换后得到的数字不一定是最小的比原数大的数。
- 另外,代码只进行了一次交换就 `break` 了,但交换的位置可能不是最优的。正确的思路应该是从右向左找到第一个可以交换的位置,并且在该位置右侧找到最右边的最小的大数进行交换。

- 检查内层循环中 `max` 的更新逻辑:当 `arr[a] > arr[i]` 时,你直接赋值 `max = a`,这样会覆盖之前找到的更大位置,但你需要的是在右侧所有大于 `arr[i]` 的数字中,找到最右边且值最小的那个。当前代码只记录了最后一个大于的位置,没有比较值的大小。
- 思考一下:如果要得到下一个更大的排列,应该从右向左找到第一个下降的位置,然后在该位置右侧找到比它大的最小数字进行交换。你的代码是从左向右找的,这可能导致错误。