C++_子集生成算法汇总

来源:互联网 发布:图集软件 编辑:程序博客网 时间:2024/05/16 19:24

增量构造算法

每次递归选取一个值放入到集合中,每次递归也输出一遍
递归结束就是无法向集合中添加元素时

#include <iostream>using namespace std;//cur用于确定子集的大小void print_subset(int *A,int n,int cur){    if(cur==0) cout << "kong";    for(int i = 0;i<cur;i++)//输出当前子集        cout << A[i] + 1 << " ";    cout << endl;    int s = cur? A[cur-1]+1 : 0;//获取当前子集的最小值,当cur为0时防止出现A[-1]    for(int i=s;i<n;i++)//每一次循环都存入一个不同的数进集合,此时变生成了不同的子集    {        A[cur]=i;        print_subset(A,n,cur+1);    }}int main(){    int n;    cout<<"输入n"<<endl;    while(cin >> n)    {        int *A=new int[n + 1];        for(int i = 1; i <= n; ++ i)            A[i] = i;        print_subset(A,n,0);    }    return 0;}

位向量法

对一个含有n个元素的集合构造一个大小也为n的布尔数组,若数组的值为true,则说明该子集包含该元素。(与布尔值组合类似)

#include <iostream>using namespace std;int print_subset(char *A, bool *B, int cur,int n){    if(cur==n)//当设置完布尔数组内的全部元素后输出    {        for(int i = 0; i<n;i++)        {            if(B[i])                cout << A[i];        }        cout << endl;    }    else    {        B[cur] = true;//选第cur个元素        print_subset(A,B,cur + 1,n);        B[cur] = false;//不选第cur个元素        print_subset(A,B,cur + 1,n);    }}int main(){    char a[] = {'a','b','c'};    bool *b = new bool(3);    int n=3;    print_subset(a,b,0,n);    return 0;}

二进制法

用一个二进制数来表示一个集合。例如,110110就可以表示{5,4,2,1,}(1说明包含元素,0表示不包含,从右往左依次为0,1,2…..)
二进制的运算
这里写图片描述
位运算符是逐位进行运算的,两个32位整数进行位运算相当于32对0/1值进行运算,对于集合来说,相当于交,并,对称差运算。
这里写图片描述

所以便可以利用二进制来表示一个集合然后枚举子集

#include <iostream>using namespace std;void print_subset(int n,int s)//输出子集s包含的元素{    for(int i=0;i<n;i++)    {        //<<把一个整型数的所有位向左移动指定的位数,移动到左边界之外的多余二进制位会被丢弃,并从右边界移入0        if(s&(1<<i))//从最右侧开始遍历s中是否含有相应的元素            cout << i+1 << " ";    }    cout << endl;}int main(){    int n=3;    for(int i=0;i<(1<<n);i++)//设置二进制数的长度,枚举子集        print_subset(3,i);    return 0;}
0 0
原创粉丝点击