子集总和 打印列表

SubsetSum Printing the list

本文关键字:列表 打印 子集      更新时间:2023-10-16

问题是打印所有总和为一个值的子集。我编写了代码来检查是否存在可能的子集。有人可以想出一个想法来打印形成总和的数字吗?下面是我的代码。为简单起见,假设数组仅包含 +ve nos。

void subsetsum(int A[], int target) {
int N = sizeof(A)/sizeof(int), sum = 0;
for(int i = 0; i < N; i++) sum += A[i];
vector<bool> V(sum + 1, 0);
V[0] = 1;
for(int i = 0; i < N; i++) 
   for(int j = sum; j >= 0; j--) {
      if(j + A[i] <= sum && V[j]) V[A[i] + j] = 1;
   }
  if(V[target]) cout << "Sumbset sum exists" << endl;
  else cout << "Sumbset sum doesnt exist" << endl;
}

首先,您需要生成所有子集

如果给定数组 [a,b,c,d],请考虑生成子集,一次从数组中获取一个元素。

子集 (X) 包括 y = foreach x in X append y to x

取 a,我们得到子集(a) = { [], [a] }

取 b,

我们得到子集 (a,b) = 子集 (a) + (子集 (a) 包括 b)

= { [], [a] } + { [b], [a,b] } = { [], [a], [b], [a,b] }

取 c, 子集 (a,b,c) = 子集 (a,b)

+ (子集 (a,b) 包括 c)

= {[], [a],[b],[a,b]} + {[c], [a,c], [b,c], [a,b,c]}

获得所有子集后,打印总和等于目标的子集。如果您不需要任何子集,您可以进一步修改上述算法。

这是javascript中的一个答案:

function subsetsum(A, target) {
//int N = sizeof(A)/sizeof(int), sum = 0;
var N = A.length, sum = 0;
//for(int i = 0; i < N; i++) sum += A[i];
for(var i = 0; i < N; i++) sum += A[i];
// vector<bool> V(sum + 1, 0);
var V = [];
V[0] = [];
for(var i = 0; i < N; i++) {
    for(var j = sum; j >= 0; j--) {
        if(j + A[i] <= sum && V[j]) {
            //Join the subset of the memoized result to this result.
            V[A[i] + j] = [A[i]].concat(V[j]);  
        } 
    }
}
console.log(V);
//evaluates to true if V[target] exists
return !!V[target];
}
函数,

用于查找vector<int>的功率集

vector<vector<int>> power_set(const vector<int>& nums) {
  if (nums.empty()) { return { {} }; }
  auto set = power_set(vector<int>(begin(nums) +1, end(nums)));
  auto tmp = set;
  for (auto& p : tmp) {
    p.push_back(nums[0]);
  }
  set.insert(end(set), begin(tmp), end(tmp));
  return set;
}

返回幂集中总和到目标的所有集合的函数

vector<vector<int>> test_sum(const vector<vector<int>>& ps, int target) {
  vector<vector<int>> v;
  for (auto& p : ps) {
    int sum = accumulate(begin(p), end(p), 0);
    if (sum == target) {
      v.push_back(p);
    }
  }
  return v;
}

我修改了您的代码以打印数字。

void subsetsum(int A[], int target) {
    int N = sizeof(A) / sizeof(int), sum = 0;
    for (int i = 0; i < N; i++) sum += A[i];
    vector<bool> V(sum + 1, 0);
    V[0] = 1;
    for (int i = 0; i < N; i++)
        for (int j = sum; j >= 0; j--) {
            if (j + A[i] <= sum && V[j]) V[A[i] + j] = 1;
        }
    if (V[target]) cout << "Sumbset sum exists" << endl;
    else cout << "Sumbset sum doesnt exist" << endl;
    if (V[target])
    {
        for (int i = N - 1; i >= 0; i--)
        {
            if (V[target - A[i]] == 1) printf("%d, ", A[i]), target -= A[i];
        }
        printf("n");
    }
}

或者这是我的矢量版本

bool subsetsum_dp(vector<int>& v, int sum)
{
    int n = v.size();
    const int MAX_ELEMENT = 100;
    const int MAX_ELEMENT_VALUE = 1000;
    static int dp[MAX_ELEMENT*MAX_ELEMENT_VALUE + 1]; memset(dp, 0, sizeof(dp));
    dp[0] = 1;
    for (int i = 0; i < n; i++)
    {
        for (int j = MAX_ELEMENT*MAX_ELEMENT_VALUE; j >= 0; j--)
        {
            if (j - v[i] < 0) continue;
            if (dp[j - v[i]]) dp[j] = 1;
        }
    }
    if (dp[sum])
    {
        for (int i = n - 1; i >= 0; i--)
        {
            if (dp[sum - v[i]] == 1) printf("%d, ", v[i]), sum -= v[i];
        }
        printf("n");
    }
    return dp[sum] ? true : false;
}