输出一个集合所有子集的元素和(Print sums of all subsets of a given set)
2016-10-14 15:22
519 查看
原文地址:http://www.geeksforgeeks.org/print-sums-subsets-given-set/
Given an array of integers, print sums of all subsets in it. Output sums can be printed in any order.
Method 1 (Recursive)
We can recursively solve this problem. There are total 2n subsets. For every element, we consider two choices, we include it in a subset and we don’t include it in a subset. Below is recursive solution based on this idea.
方法一(递归)
我们可以递归地解决这个问题,这个集合共有2n个子集。对于每一个元素,我们考虑两种选择,子集中包含这个元素或者不包含这个元素。下面是基于这个想法的递归方法。
// C++ program to print sums of all possible
// subsets.
#include<bits/stdc++.h>
using namespace std;
// Prints sums of all subsets of arr[l..r]
void subsetSums(int arr[], int l, int r,
int sum=0)
{
// Print current subset
if (l > r)
{
cout << sum << " ";
return;
}
// Subset including arr[l]
subsetSums(arr, l+1, r, sum+arr[l]);
// Subset excluding arr[l]
subsetSums(arr, l+1, r, sum);
}
// Driver code
int main()
{
int arr[] = {5, 4, 3};
int n = sizeof(arr)/sizeof(arr[0]);
subsetSums(arr, 0, n-1);
return 0;
}
Output:
Method 2 (Iterative)
As discussed above, there are total 2n subsets. The idea is generate loop from 0 to 2n – 1. For every number, pick all array elements which correspond to 1s in binary representation of current number.
方法二(迭代)
正如前面所讨论的,这个集合有2n个子集。这个想法就是从0到2n – 1循环。对于每个数字,挑出所有的数组元素,这些元素表示出二进制的时候每一位全部是1.
// Iterative C++ program to print sums of all
// possible subsets.
#include<bits/stdc++.h>
using namespace std;
// Prints sums of all subsets of array
void subsetSums(int arr[], int n)
{
// There are totoal 2^n subsets
long long total = 1<<n;
// Consider all numbers from 0 to 2^n - 1
for (long long i=0; i<total; i++)
{
long long sum = 0;
// Consider binary reprsentation of
// current i to decide which elements
// to pick.
for (int j=0; j<n; j++)
if (i & (1<<j))
sum += arr[j];
// Print sum of picked elements.
cout << sum << " ";
}
}
// Driver code
int main()
{
int arr[] = {5, 4, 3};
int n = sizeof(arr)/sizeof(arr[0]);
subsetSums(arr, 0, n-1);
return 0;
}
Output:
Thanks to cfh for suggesting above iterative solution in a comment.
Note: We haven’t actually created sub-sets to find their sums rather we have just used recursion to find sum of non-contiguous sub-sets of the given set.
The above mentioned techniques can be used to perform various operations on sub-sets like multiplication, division, XOR, OR, etc, without actually creating and storing the sub-sets and thus making the program memory efficient.
注意:我们还没有真正创建子集来得到它们的值,而是我们只是用递归得到已知集合子集的非连续和。
以上所提到的技术可以用于各种子集的操作,例如:乘法、除法、XOR、OR等,没有真正创建并存储子集,因此可以使得代码使用内存更有效。
Given an array of integers, print sums of all subsets in it. Output sums can be printed in any order.
Input : arr[] = {2, 3} Output: 0 2 3 5 Input : arr[] = {2, 4, 5} Output : 0 2 4 5 6 7 9 11
Method 1 (Recursive)
We can recursively solve this problem. There are total 2n subsets. For every element, we consider two choices, we include it in a subset and we don’t include it in a subset. Below is recursive solution based on this idea.
方法一(递归)
我们可以递归地解决这个问题,这个集合共有2n个子集。对于每一个元素,我们考虑两种选择,子集中包含这个元素或者不包含这个元素。下面是基于这个想法的递归方法。
// C++ program to print sums of all possible
// subsets.
#include<bits/stdc++.h>
using namespace std;
// Prints sums of all subsets of arr[l..r]
void subsetSums(int arr[], int l, int r,
int sum=0)
{
// Print current subset
if (l > r)
{
cout << sum << " ";
return;
}
// Subset including arr[l]
subsetSums(arr, l+1, r, sum+arr[l]);
// Subset excluding arr[l]
subsetSums(arr, l+1, r, sum);
}
// Driver code
int main()
{
int arr[] = {5, 4, 3};
int n = sizeof(arr)/sizeof(arr[0]);
subsetSums(arr, 0, n-1);
return 0;
}
Output:
12 9 8 5 7 4 3 0
Method 2 (Iterative)
As discussed above, there are total 2n subsets. The idea is generate loop from 0 to 2n – 1. For every number, pick all array elements which correspond to 1s in binary representation of current number.
方法二(迭代)
正如前面所讨论的,这个集合有2n个子集。这个想法就是从0到2n – 1循环。对于每个数字,挑出所有的数组元素,这些元素表示出二进制的时候每一位全部是1.
// Iterative C++ program to print sums of all
// possible subsets.
#include<bits/stdc++.h>
using namespace std;
// Prints sums of all subsets of array
void subsetSums(int arr[], int n)
{
// There are totoal 2^n subsets
long long total = 1<<n;
// Consider all numbers from 0 to 2^n - 1
for (long long i=0; i<total; i++)
{
long long sum = 0;
// Consider binary reprsentation of
// current i to decide which elements
// to pick.
for (int j=0; j<n; j++)
if (i & (1<<j))
sum += arr[j];
// Print sum of picked elements.
cout << sum << " ";
}
}
// Driver code
int main()
{
int arr[] = {5, 4, 3};
int n = sizeof(arr)/sizeof(arr[0]);
subsetSums(arr, 0, n-1);
return 0;
}
Output:
12 9 8 5 7 4 3 0
Thanks to cfh for suggesting above iterative solution in a comment.
Note: We haven’t actually created sub-sets to find their sums rather we have just used recursion to find sum of non-contiguous sub-sets of the given set.
The above mentioned techniques can be used to perform various operations on sub-sets like multiplication, division, XOR, OR, etc, without actually creating and storing the sub-sets and thus making the program memory efficient.
注意:我们还没有真正创建子集来得到它们的值,而是我们只是用递归得到已知集合子集的非连续和。
以上所提到的技术可以用于各种子集的操作,例如:乘法、除法、XOR、OR等,没有真正创建并存储子集,因此可以使得代码使用内存更有效。
相关文章推荐
- 给出一个set的字符和一个正数k,求所有由这个set能组成长度为k的字符串集合 print-all-combinations-of-given-length
- 给定一个set字符和一个正数k,找出所有该做set它可以由长度构成k该字符串集合 print-all-combinations-of-given-length
- 有一个集合A,它又n个元素,请用回溯法输出它所有的子集。
- 输出一个集合的所有子集(算法)
- 输入一个集合,输出这个集合的所有子集
- 给定一个集合和一个正整数c,判定是否存在该集合的子集,使其所有元素的和等于给定的正整数c?
- 给定一个集合,输出它的所有子集
- 输出一个集合的所有子集
- 请编写一个递归函数,用来输出n个元素的所有子集。例如,三个元素{a,b,c}的所有子集是:{},{a},{b},{c},{a,c},{ac},{b,c},{a,b,c}.
- LeetCode(Subsets)找出一个集合的所有子集
- 输出一个集合的所有子集
- 输出一个集合的所有子集,从长到短
- 写一个递归函数,用来输出n个元素的所有子集。
- LeetCode Online Judge:Given a set of distinct integers, S, return all possible subsets.
- 给定一个集合,输出它的所有子集(JAVA实现)
- 集合之间的操作util-在全集allSet中标识出在子集sonSet 出现过的元素
- 输出一个集合的幂集(所有子集)
- 输出一个集合的所有子集(算法)
- 输出一个集合的所有子集(算法)
- 求一个集合的所有子集 输出一个数所有平方和的情况 背包问题的递归解决