zoukankan      html  css  js  c++  java
  • C/C++ 子集生成算法整理

    个人笔记,仅供复习

    1.概念:给定一个集合,枚举所有可能的子集。

    2.常用算法

    • 增量构造法
    • 位向量法
    • 二进制法

    3.增量构造法

    3.1 思路:一次选出一个元素放到集合中。

    3.2 代码实例:

    void print_subset(int n,int *A,int cur){
    	for(int i = 0;i < cur;i++)	cout << A[i] << " ";//打印当前子集 
    	cout << endl;
    	int s = cur ? A[cur-1]+1:0;
    	for(int i = s;i < n;i++){
    		A[cur] = i;
    		print_subset(n,A,cur+1);
    	}
    }

    3.3代码解析:

    • 其中cur指的是当前元素的位置。上述代码的作用是读入n,输出{0,1,2,3,…,n-1}的所有子集。第五行中的 s 指的是 当前还可以放入集合A中的最小元素。
    • 上述代码用到了定序的技巧。所谓的定序就是规定集合A中的所有元素按照从小到大排列,这样就不会出现{1,2}和{2,1}这样重复的集合了。
    • 上述代码的作用是输出{0,1,2,3,…,n-1}的所有子集。如果要输出自定义集合的子集,只需要将A[i]当作下标,这样就可以输出自定义的集合了。

    4.位向量法

    4.1 思路:构造一个位向量B[i],而不是直接构造集合本身,其中B[i] = 1,当且仅当i在子集A中

    4.2 代码实例:

    void print_subset(int n,int *B,int cur){
    	if(cur == n){
    		for(int i = 0;i < cur;i++)
    			if(B[i])	cout << i << " ";
    		cout << endl;
    		return;
    	}
    	B[cur] = 1;
    	print_subset(n,B,cur+1);
    	B[cur] = 0;
    	print_subset(n,B,cur+1);
    }

    5.二进制法

    5.1 思路:可以用二进制表示子集,其中从右往左第i位(从0开始编号)表示元素i是否在集合中(1表示在,0表示不在)

    5.2 代码实例:

    #include<iostream>
    using namespace std;
    void print_subset(int n,int s){
    	for(int i = 0;i < n;i++)
    		if(s&(1<<i))	cout << i << " ";
    	cout << endl;
    }
    int main()
    {
    	int n;
    	cin >> n;
    	for(int i = 0;i < (1<<n);i++)
    		print_subset(n,i);//枚举各子集对应的编码0,1,2,…,2^n-1.
    	return 0;
    }

    5.3 代码解析:

    • 首先要明白位移运算符(<<)的作用;第五行对1使用位移运算符,(1<<i)指的是将1向左移动i位,右面补0
    • 若一个集合中有n个元素,那么它的子集有2^n个,而假设每个元素只有存在(1)和不存在(0)两种状态,那么它的子集可以看成不同的二进制串,即每个子集可以代表且仅代表一个不同的十进制数,共2^n个不同的十进制数,这也就说明了每个十进制数代表了一个不同的二进制串,即每个十进制数代表了一个子集,因此可以有上述代码第13行写法。具体关系如下:
                                        十进制数——>二进制串——>从右往左读串,是1则当前位数存在于此集合
  • 相关阅读:
    AJAX
    大前端面试一(基础)
    webpack打包vue -->简易讲解
    vue实现原理
    Spring boot 线上部署
    javascript 事件
    React native采坑路 Running 1 of 1 custom shell scripts
    PHP swoole实现redis订阅和发布
    JAVA 注解和反射
    微信公众平台获取用户地理位置之开发文档详解
  • 原文地址:https://www.cnblogs.com/long98/p/10352238.html
Copyright © 2011-2022 走看看