Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 递归与位掩码用于获取向量元素的所有组合_C++_Algorithm_Recursion_Combinations_Bitmask - Fatal编程技术网

C++ 递归与位掩码用于获取向量元素的所有组合

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

在为编程竞赛(如ACM、代码阻塞等)练习时,我遇到了一些问题,需要生成一些向量元素的所有可能组合

假设我有向量{1,2,3},我需要生成以下组合(顺序不重要):

到目前为止,我已经用以下代码完成了:

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;
}