C#生成1-9无重复组合代码故障:需遍历至首列数值为9
解决C#组合生成代码提前终止的问题
我帮你找出问题所在啦!你的代码在生成完一个完整组合后直接break跳出了循环,导致没法正确回溯生成后续的组合分支。咱们来一步步修正这个逻辑:
问题根源分析
原代码中,当index == k生成完一个完整组合后,执行了break,这会直接终止当前的while (value <= n)循环。这就导致程序无法继续尝试增大当前位置的数值,也没法回溯到前面的位置去替换更大的起始值,自然就停在了最后一个以4开头的组合4-5-6-7-8-9。
另外要说明的是:按照无重复递增组合的定义,当k=6、n=9时,首列的最大值确实是4(因为后面需要5个比它大的数,9-5=4),所以不存在首列到9的组合——如果强行要首列到9,那后面需要5个比9大的数,显然不符合n=9的限制哦。
修改后的完整代码
static void Main() { Console.Write("n = "); var n = int.Parse(Console.ReadLine()); Console.Write("k = "); var k = int.Parse(Console.ReadLine()); foreach (var combo in Combinations(k, n)) { Console.WriteLine(string.Join(", ", combo)); } Console.ReadLine(); } private static IEnumerable<int[]> Combinations(int k, int n) { var result = new int[k]; // 栈中存储当前要填充的索引和该位置的起始值 var stack = new Stack<(int index, int startValue)>(); stack.Push((0, 1)); while (stack.Count > 0) { var current = stack.Pop(); int index = current.index; int value = current.startValue; // 确保当前值后面还有足够的数填满剩余位置 while (value <= n - (k - index - 1)) { result[index] = value; if (index == k - 1) { // 返回数组副本,避免后续修改影响已输出的结果 yield return (int[])result.Clone(); } else { // 将下一个位置的任务压入栈,起始值为当前值+1 stack.Push((index + 1, value + 1)); } // 尝试当前位置的下一个更大数值 value++; } } }
关键改动说明
- 栈存储结构优化:不再只存单一数值,而是存储
(索引, 起始值)的元组,让回溯逻辑更清晰,明确知道当前要处理哪个位置、从哪个数值开始。 - 移除break逻辑:生成完整组合后不再跳出循环,而是继续递增
value,尝试当前位置的更大数值,生成更多组合。 - 添加合法性判断:
value <= n - (k - index - 1)确保当前选择的数值后面还有足够多的数来填满剩余的位置,避免无效的遍历。 - 返回数组副本:用
result.Clone()返回新数组,因为原数组是引用类型,直接返回会导致后续修改覆盖已输出的结果。
内容的提问来源于stack exchange,提问作者Nactrem
相关产品推荐
相关产品推荐

