子集总和 打印列表
SubsetSum Printing the list
问题是打印所有总和为一个值的子集。我编写了代码来检查是否存在可能的子集。有人可以想出一个想法来打印形成总和的数字吗?下面是我的代码。为简单起见,假设数组仅包含 +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] }
+ (子集 (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;
}
相关文章:
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 链接列表运算符重载没有打印出我想要的内容
- 直接 2D 呈现到命令列表和打印:图片压缩
- C++声明双链表,使用两个 for 循环双向遍历列表并打印
- 如何获取列表的每个对象并调用getName方法来打印其名称
- 只有我的"链接列表"中的第一个节点正在打印
- C++ - 使用 std::list,如何打印对象的私有成员的链接列表?
- C++使用相反的顺序打印带有逗号的列表
- 如何实现否定用户输入退出程序和打印列表?
- 打印/修改类对象的特定成员变量,其类定义列表 (STL) 包含的元素类型
- C++:一种在列表中打印所有对的优雅方式
- C 打印集合列表
- 如何打印简单的链接列表(C )
- 如何编写循环以通过列表迭代并打印列表中每个元素的数据的数据
- 使用for_each从对象列表中调用打印功能
- 我的链接列表打印功能进入无限循环
- 链接列表打印null -C
- 链接列表打印不起作用.
- 将整数列表打印为逗号分隔的数字列表,每行最多 10 个
- 奇怪的列表打印函数行为。如果我打印"n"则有效,如果我删除它则不起作用