递归函数实现N拆分为K个非负整数划分的代码问题排查
问题排查与代码修正
你的代码无法正确输出所有划分的原因主要集中在缺失关键函数定义、终止条件逻辑不严谨以及输出写法错误这几点,以下是具体分析和修正方案:
核心问题分析
- 未实现
min函数:C语言标准库没有内置min函数,若未自行定义,代码会出现编译错误或未定义行为,直接破坏递归遍历的逻辑。 - 终止条件不严谨:原条件
k <=0 && a <=0会包含k<0的无效情况,且未明确区分“分配完K个元素”和“剩余值为0”的判断逻辑,导致部分合法划分无法触发输出。 - 输出换行写法错误:
puts(" ");是HTML转义后的错误写法,实际应使用puts("");或printf("\n");来生成正确的换行。 - 缺少负数剩余值的提前终止:当剩余总和
a为负数时,无需继续递归,直接返回即可避免无效调用。
修正后的完整代码
#include <stdio.h> // 自定义min宏,取两个整数的较小值 #define min(a, b) ((a) < (b) ? (a) : (b)) void f(int a, int k, int secondArray[], int used) { // 剩余总和为负,直接终止递归 if (a < 0) return; // 已分配完K个元素,检查剩余总和是否为0 if (k == 0) { if (a == 0) { for (int i = 0; i < used; i++) { printf("%d ", secondArray[i]); } puts(""); } return; } // 确定当前元素的最大值:保证非递增顺序,不超过前一个元素或剩余总和 int max_i = (used > 0) ? min(secondArray[used-1], a) : a; for (int i = max_i; i >= 0; i--) { secondArray[used] = i; // 递归:剩余总和减去当前值,剩余元素个数减1,已使用位置加1 f(a - i, k - 1, secondArray, used + 1); } } // 示例调用 int main() { int arr[3]; // N=5,K=3,初始已使用位置为0 f(5, 3, arr, 0); return 0; }
调用说明
在main函数中,需要传入与K长度匹配的数组(示例中K=3,数组长度为3),初始调用参数为f(N, K, 数组名, 0),其中最后一个参数used表示当前已填充的元素个数,初始为0。
修正后的代码运行后,会正确输出所有非递增顺序的划分:
5 0 0 4 1 0 3 2 0 3 1 1 2 2 1
内容的提问来源于stack exchange,提问作者Bubi
相关产品推荐
相关产品推荐

