我正在尝试创建一个程序来查找其元素总和为特定目标的所有子集。我的逻辑是:假设我有一个包含6个元素的数组,就像这个一样
{3,2,4,1,1,9}
。
要找到元素总和为数字5的子集,我只需得到第一个元素,如果它的值小于5,那么我将移动到数组的下一个元素,并查找其元素总和的子集差异:第一个元素的5值,依此类推。 当然,如果元素的值大于5,那么我将移动到下一个元素。
我一直在尝试使用递归函数来执行此操作,其中我将传递我的数组。
我的问题是我无法理解如何将我的数组传递给我的函数以及如何再次使用我的函数移动到下一个元素。说实话,我对这个主题进行了研究,但我找不到任何对我有帮助的东西。
我使用C并且我声明我的函数void subset(int x[],int n);
,其中n
是我的数组元素的数量。我无法理解x[]
部分。我哥哥告诉我这样做,但我不明白为什么。
答案 0 :(得分:0)
所以你试图将你的数组传递给一个函数?数组中的元素或成员将使用括号“[]”引用,例如在数组“int arry [6] = {1,2,3,6,5};”中引用第一个元素是数字“1”,我们可以使用arry [0]
访问它在充分尊重的情况下,您似乎没有在这方面进行“诚实的研究”,我建议您继续,因为数组是几乎所有语言中不可或缺的一部分。
下面是一些c代码,可以帮助您开始做作业。 int arry []是一种完全不同的类型,而不是“int arry”。括号部分告诉我们它是一个数组。
#include <stdio.h>
int main()
{
int arry[6]={1,2,3,6,5};
myFunction(arry,4);
return 0;
}
int myFunction(int myarr[], int x){
printf("the number %d element is %d",x+1,myarr[4]);
return 0;
}
答案 1 :(得分:0)
这是一个精心设计的解决方案。对于给定的数据,它产生:
Data (6): 3 2 4 1 1 9
Found: 3 + 2 = 5
Found: 3 + 1 + 1 = 5
Found: 4 + 1 = 5
Found: 4 + 1 = 5
关键是要了解解决问题所需的数据。你需要知道:
“到目前为止的总和”可以从列表中已有的元素的数量和列表中获得,但也可以方便地传递它。这给出了一个6参数的递归函数。它使用所需的目标调用,0表示到目前为止的总和,要搜索的完整元素数组,以及一个足以容纳所有要搜索的元素的空列表。这发生在main()
中。该函数标识它是否找到了添加到目标的任何列表(如果不是则返回0,如果没有则返回1),因此测试和报告以及main()
的结束。
在该功能中,检查各种不可能的条件并挽救。如果在顶部用debug = 1
编译,则在输入函数时打印数据。扫描剩余的未检查元素,检测元素何时使总和等于目标并报告执行此操作的列表(注意它丢失原始索引信息;您可以添加它,但它是读者的练习)。如果元素足够小以便为另一个元素留出空间,则将该元素添加到找到的列表中,并将该数组的其余部分传递给对该函数的递归调用。其他功能是微不足道的打印循环。
当目标设置为40(而不是5)时,它会正确报告未找到任何子集,最多可添加40个。
可能有更简单的方法来编码它,但我在病态上反对不必要的全局变量(我认为debug
是一种有条件地编译代码而不是全局变量的方式)。可以将参数列表打包在一个结构中;不过,我不确定这会有多大帮助。如果我包含bool
,我可以使用int
代替false
(以及true
和0
代替1
和<stdbool.h>
) 。代码是不可避免的C99或C11;它不会按照C89编写的程序进行编译(但要使它与C89一起使用并不困难)。
代码:
#include <stdio.h>
static const int debug = 0;
static void found_one(int num, int *list)
{
printf("Found: ");
char const *pad = "";
int sum = 0;
for (int i = 0; i < num; i++)
{
printf("%s%d", pad, list[i]);
pad = " + ";
sum += list[i];
}
printf(" = %d\n", sum);
}
static void print_array(char const *tag, int num, int *arr)
{
printf("%s (%d):", tag, num);
for (int i = 0; i < num; i++)
printf(" %d", arr[i]);
putchar('\n');
}
static int find_subsets(int target, int sumsofar, int num_src, int *src,
int num_dst, int *dst)
{
if (sumsofar >= target)
return 0;
if (num_src <= 0)
return 0;
if (debug)
{
printf("-->> %s: sumsofar = %d, num_src = %d, num_dst = %d\n",
__func__, sumsofar, num_src, num_dst);
print_array("Source", num_src, src);
print_array("Dest'n", num_dst, dst);
}
int rc = 0;
int max = target - sumsofar;
for (int i = 0; i < num_src; i++)
{
if (src[i] == max)
{
dst[num_dst] = src[i];
found_one(num_dst + 1, dst);
rc = 1;
}
else if (src[i] < max)
{
dst[num_dst] = src[i];
if (find_subsets(target, sumsofar + src[i], num_src - (i + 1),
src + (i + 1), num_dst + 1, dst))
rc = 1;
}
}
if (debug)
printf("<<-- %s: %d\n", __func__, rc);
return rc;
}
int main(void)
{
int data[] = { 3, 2, 4, 1, 1, 9 };
enum { NUM_DATA = sizeof(data) / sizeof(data[0]) };
int subset[NUM_DATA];
int target = 5;
print_array("Data", NUM_DATA, data);
if (find_subsets(target, 0, NUM_DATA, data, 0, subset) == 0)
printf("Did not find any subsets totalling %d\n", target);
return 0;
}