我正在使用下面的代码解决子集求和问题的一个变体。这个问题需要从一个更大的集合(超集)中生成11个整数的子集,并检查它是否与特定值(endsum)相匹配。优化子集求和实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
int endsum = 0, supersetsize = 0, done = 0;
int superset[] = {1,30,10,7,11,27,3,5,6,50,45,32,25,67,13,37,19,52,18,9};
int combo = 0;
int searchForPlayerInArray(int arr[], int player) {
for (int i=0; i<11; i++) {
if (arr[i] == player) {
return 1;
}
}
return 0;
}
int sumOfArray(int arr[]) {
int res = 0;
for (int i=0; i<11; i++) {
res+=arr[i];
}
return res;
}
void printArray(int arr[], int arrSize) {
for (int j=0; j<arrSize; j++) {
printf("%2d ",arr[j]);
}
printf("= %d\n",endsum);
}
void permute(int subset[], int pos, int sspos) {
if (done) { //when a correct solution has been found, stop recursion
return;
}
if (sspos == supersetsize) { // out of possible additions
return;
}
if (pos == 11) { //is the current subset 11 ints long?
int res = sumOfArray(subset);
combo++;
if (res == endsum) { //if the sum of the array matches the wanted sum, print
printArray(subset,11);
done = 1;
}
return;
}
for (int i=sspos; i<supersetsize; i++) {
//assert(pos < 11);
//assert(i+1 <= supersetsize);
subset[pos] = superset[i];
permute(subset,pos+1,i+1);
}
}
int main(void) {
endsum = 110;
supersetsize = 20;
int *arr;
arr = malloc(supersetsize*sizeof(int));
int i;
for (i=0; i<supersetsize; i++) {
arr[i] = 0;
}
permute(arr,0,0);
printf("Combinations: %d",combo);
return 0;
}
虽然这种解决方案适用于小型的超集(< 15),它是缓慢和低效,因为它产生的每一种可能的排列,而不是仅仅独特的。我怎样才能优化它来生成唯一的子集?
编辑:根据大众需求添加完整的源代码。
这是在C++还是C?它像C一样发臭,但从技术上讲,我猜可能是C++。 – Puppy 2011-06-04 12:51:16
这似乎是我的标准子集合。它是否正确?如果是这样,我建议你自己多做一点研究。在StackOverflow和其他地方有很多关于这个问题的讨论。关闭作为愚蠢? – 2011-06-04 13:37:05
@AaronMcDaid非标准部分是缺乏负整数和非零答案。 – Gorkamorka 2011-06-04 21:49:03