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

增量构造算法

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

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

int main()
{
    int n;
    cout<<"输入n"<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 

using namespace std;

int print_subset(char *A, bool *B, int cur,int n)
{
    if(cur==n)//当设置完布尔数组内的全部元素后输出
    {
        for(int i = 0; iif(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…..)
二进制的运算
C++_子集生成算法汇总_第1张图片
位运算符是逐位进行运算的,两个32位整数进行位运算相当于32对0/1值进行运算,对于集合来说,相当于交,并,对称差运算。
这里写图片描述

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

#include 

using namespace std;

void print_subset(int n,int s)//输出子集s包含的元素
{
    for(int i=0;i//<<把一个整型数的所有位向左移动指定的位数,移动到左边界之外的多余二进制位会被丢弃,并从右边界移入0
        if(s&(1<//从最右侧开始遍历s中是否含有相应的元素
            cout << i+1 << " ";
    }
    cout << endl;

}

int main()
{
    int n=3;
    for(int i=0;i<(1<//设置二进制数的长度,枚举子集
        print_subset(3,i);
    return 0;
}

你可能感兴趣的:(C++,计算机算法,递归)