C++ 递归与位掩码用于获取向量元素的所有组合
在为编程竞赛(如ACM、代码阻塞等)练习时,我遇到了一些问题,需要生成一些向量元素的所有可能组合 假设我有向量{1,2,3},我需要生成以下组合(顺序不重要): 到目前为止,我已经用以下代码完成了:C++ 递归与位掩码用于获取向量元素的所有组合,c++,algorithm,recursion,combinations,bitmask,C++,Algorithm,Recursion,Combinations,Bitmask,在为编程竞赛(如ACM、代码阻塞等)练习时,我遇到了一些问题,需要生成一些向量元素的所有可能组合 假设我有向量{1,2,3},我需要生成以下组合(顺序不重要): 到目前为止,我已经用以下代码完成了: void getCombinations(int a) { printCombination(); for(int j=a;j<vec.size();j++) { combination.pb(vec.at(j)); getCombina
void getCombinations(int a)
{
printCombination();
for(int j=a;j<vec.size();j++)
{
combination.pb(vec.at(j));
getCombinations(j+1);
combination.pop_back();
}
}
void getcompositions(int a)
{
打印组合();
对于(int j=a;j可以得到的组合数是2^n,其中n是元素数。您可以将0到2^n-1之间的每个整数解释为掩码。在您的示例中(元素1、2、3)您有3个元素,因此掩码将为000、001、010、011、100、101、110和111。让掩码中的每个位置代表一个元素。对于有1的位置,取相应的元素,否则如果该位置包含0,则忽略该元素。例如,数字5将是掩码101,它将生成th是组合:1,3
如果您想获得快速且相对较短的代码,可以这样做:
#include <cstdio>
#include <vector>
using namespace std;
int main(){
vector<int> elements;
elements.push_back(1);
elements.push_back(2);
elements.push_back(3);
// 1<<n is essentially pow(2, n), but much faster and only for integers
// the iterator i will be our mask i.e. its binary form will tell us which elements to use and which not
for (int i=0;i<(1<<elements.size());++i){
printf("Combination #%d:", i+1);
for (int j=0;j<elements.size();++j){
// 1<<j shifts the 1 for j places and then we check j-th binary digit of i
if (i&(1<<j)){
printf(" %d", elements[j]);
}
}
printf("\n");
}
return 0;
}
#包括
#包括
使用名称空间std;
int main(){
矢量元素;
元素。推回(1);
元素。推回(2);
元素。推回(3);
//1“我遇到了一些问题,需要我生成所有可能的组合”
-我参加了公平的比赛,我认为我从未见过这样做是正确解决方案的问题(即足够有效)。您通常需要智能地生成有限的子集,只生成正确的子集,或者只计算它们而不生成它们。我提到了ACM和Code Jam,因为每个人都知道它们。否则,我是马其顿的一名高中生,我参加了全国性的比赛,那里的问题比比赛中的问题要容易得多我想不出有什么,但我确信我已经使用了那个算法在某个地方得到了满分。我也使用了那个递归的变化来得到大小为M的子集,但我不确定是否可以用位屏蔽有效地做到这一点?如果可能的话,我也想看到。你能解释一下if(I)吗&(1当然可以。让我们先分解I&(1)
#include <cstdio>
#include <vector>
using namespace std;
int main(){
vector<int> elements;
elements.push_back(1);
elements.push_back(2);
elements.push_back(3);
// 1<<n is essentially pow(2, n), but much faster and only for integers
// the iterator i will be our mask i.e. its binary form will tell us which elements to use and which not
for (int i=0;i<(1<<elements.size());++i){
printf("Combination #%d:", i+1);
for (int j=0;j<elements.size();++j){
// 1<<j shifts the 1 for j places and then we check j-th binary digit of i
if (i&(1<<j)){
printf(" %d", elements[j]);
}
}
printf("\n");
}
return 0;
}