Online Compiler C

#include <stdio.h> int main() { int n; scanf("%d", &n); int a[10], ai = 0; while (n > 0) { a[ai] = n % 10; ai++; n = n / 10; } int num[10], ni = 0; while (ai > 0) { ai--; num[ni] = a[ai]; ni++; } int max = num[0], start = 0, now = 0; for (int j = 0; j < ni; j++) { for (int i = start; i < ni; i++) { if (max <= num[i]) { max = num[i]; now = i; } } if (num[j] == max) { start++; max = num[start]; } if (num[j] < max) { num[now] = num[j]; num[j] = max; for (int i = 0; i < ni; i++) { printf("%d", num[i]); } return 0; } } }
这段代码的功能是:读入一个整数,将其各位数字按原顺序存入数组,然后尝试找到第一个可以交换的位置,使得交换后得到的数字比原数字大。但代码的逻辑存在一些问题。

- 代码先通过取余和除法将数字的各位逆序存入数组 `a`,再通过另一个循环将其正序存入数组 `num`。这部分是正确的。
- 之后的三重循环试图寻找一个“下一个更大的排列”,但实现方式有误。外层循环 `j` 遍历每一位,内层循环从 `start` 开始找当前及之后的最大值。当发现当前位 `num[j]` 小于后面某位最大值时,就交换并输出。但这里的 `start` 和 `max` 更新逻辑不清晰,导致可能找不到正确的交换位置,或者交换后得到的数字不是最小的更大值。

- 提示1:思考一下,要得到比原数大的最小数,应该从右向左找到第一个下降的位置,而不是从左向右找最大值。例如对于数字 12345,应该交换哪两位才能得到下一个更大的数?
- 提示2:当前代码中,当 `num[j] < max` 时直接交换并输出,但 `max` 可能不是最右边那个比 `num[j]` 大的最小数字。例如数字 132,交换 1 和 3 得到 312,但正确的下一个更大数是 213。想一想如何找到正确的交换对象。