递归生成元素和为指定值的数组:C语言代码无输出排查
问题描述
给定数组v[]={2,6}和目标值d=10,需要输出所有元素和等于d的数组组合(示例输出如下):
2 2 2 2 2 6 2 2 2 6 2 2 2 6
但编写的C语言递归程序无任何输出,怀疑问题出在回溯逻辑部分,当前代码如下:
#include <stdio.h> #include <stdlib.h> void findSolutions(int v[], int n, int d, int current[], int index) { if(index>n) { current=realloc(current,index*sizeof (int)); } if (d == 0) { for (int i = 0; i < index; i++) { printf("%d ", current[i]); } printf("\n"); return; } if (d < 0 || index >= n) { return; } current[index] = v[index]; findSolutions(v, n, d - v[index], current, index + 1); findSolutions(v, n, d, current, index + 1); } int main() { int v[] = {2, 6}; int n = 2; int d = 10; int *current= malloc(n*sizeof(int)); findSolutions(v, n, d, current, 0); return 0; }
问题核心原因
你的代码存在三个关键问题,导致无法生成预期结果:
- 递归逻辑错误:当前代码限制每个元素只能被选择一次(通过
index+1推进索引),但题目要求允许重复使用数组元素,同时需要生成元素位置不同的排列。 - 终止条件过严:
index >= n的判断会在遍历完数组一次后直接终止递归,无法实现重复选择元素的逻辑。 - 数组扩容无效:
realloc是值传递,函数内修改的current指针不会影响上层调用,而且扩容逻辑完全不符合动态添加元素的需求。
修正后的代码
#include <stdio.h> #include <stdlib.h> void findSolutions(int v[], int n, int d, int current[], int currentLen) { // 找到符合条件的组合,输出结果 if (d == 0) { for (int i = 0; i < currentLen; i++) { printf("%d ", current[i]); } printf("\n"); return; } // 剩余目标值为负,直接返回 if (d < 0) { return; } // 遍历数组所有元素,允许重复选择 for (int i = 0; i < n; i++) { // 动态扩容当前组合数组 current = realloc(current, (currentLen + 1) * sizeof(int)); current[currentLen] = v[i]; // 递归:目标值减去当前元素,组合长度+1 findSolutions(v, n, d - v[i], current, currentLen + 1); } } int main() { int v[] = {2, 6}; int n = 2; int d = 10; int *current = malloc(sizeof(int)); findSolutions(v, n, d, current, 0); // 释放动态分配的内存 free(current); return 0; }
代码说明
- 允许重复选择元素:递归时遍历数组所有元素(从索引0开始),而非仅推进索引,这样可以生成所有包含重复元素的组合和排列。
- 简化终止条件:仅保留
d < 0的终止判断,当d == 0时直接输出当前组合。 - 动态扩容组合数组:每次添加元素时用
realloc调整数组大小,确保能存储当前组合的所有元素。 - 自动回溯:递归返回后,下一次循环会覆盖当前组合的末尾位置,天然实现回溯效果,无需手动删除元素。
内容的提问来源于stack exchange,提问作者Severjan Lici
相关产品推荐
相关产品推荐

