我正在使用下面的代碼解決子集求和問題的一個變體。這個問題需要從一個更大的集合(超集)中生成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