紫书之子集生成三种算法

简介: 紫书之子集生成三种算法

问题描述:

给定一个集合,比如{1,2,3,4},要生成所有的子集(不包括空集,也就是2^n-1个集合)

注: n个元素集合有2^n个子集.


1.增量构造法

思路:在已有子集的基础上不断增加新的元素,一直到无法继续添加为止. 另外因为我们排序的是数组的索引,是从小到大的,就不会出现重复的了.

参考代码

#include<iostream>
#include<cstdio>
using namespace std;
int A[101];//存放集合元素下标的的数组
void print_subset(int n,int *A,int cur){//cur:当前A序列中元素的个数.   
  for(int i = 0;i < cur;i++){//打印当前集合,每次进入都要进行打印 
    printf("%d",A[i]);
  }
  printf("\n");
  int s = cur ? A[cur-1]+1:0; // 确定下一个元素的最小值
  for(int i = s; i < n;i++){//从前往后进行枚举  第一次 A 一定包含A[s]元素, 第二轮则是一定包含A[s+1]元素  A序列中的元素一定都是从小到达的 
    A[cur] = i;
    print_subset(n,A,cur+1);//继续构造子集. 
  } 
} 
int main()
{
  int n;
  scanf("%d",&n);
  print_subset(n,A,0);
  return 0;
} 

运行结果:

20210618172839739.png

2.位向量法

思路:使用一个数组来进行标记对应位置的元素是否存在,标记位置为0表示不存在,为1表示存在.

参考代码
#include<iostream>
#include<cstdio>
using namespace std;
int B[10];
void print_subset(int n,int *B,int cur){
  if(cur==n){
    for(int i = 0; i < cur;i++){
      if(B[i]){
        printf("%d",i); 
      }
    }
    printf("\n"); 
    return;
  }
  B[cur] = 1;//选第cur个元素
  print_subset(n,B,cur+1);
  B[cur] = 0;//不选第cur个元素
  print_subset(n,B,cur+1); 
} 
int main()
{
  int n;
  scanf("%d",&n);
  print_subset(n,B,0);
  return 0;
}

运行结果

20210618173130940.png


3.二进制法

有点复杂,自己目前还有点迷糊.

#include<cstdio>
#include<iostream>
using namespace std;
void print_subset(int n,int s){
  for(int i = 0;i < n;i++){
    if(s&(1<<i)){
      printf("%d",i);
    }
  }
  printf("\n");
}
int main()
{
  int n;
  scanf("%d",&n);
  for(int i = 0; i < (1<<n);i++){//  
    print_subset(n,i);
  }
  return 0;
}
相关文章
|
6月前
|
存储 算法 程序员
【算法训练-回溯算法 二】【子集组合问题】子集、组合、子集II、组合总和
【算法训练-回溯算法 二】【子集组合问题】子集、组合、子集II、组合总和
58 0
|
5月前
|
机器学习/深度学习 存储 算法
LeetCode题目 90:五种算法 回溯\迭代\位掩码\字典树\动态规划实现 子集ll
LeetCode题目 90:五种算法 回溯\迭代\位掩码\字典树\动态规划实现 子集ll
|
5月前
|
算法 搜索推荐
数据结构和算法——快速排序(算法概述、选主元、子集划分、小规模数据的处理、算法实现)
数据结构和算法——快速排序(算法概述、选主元、子集划分、小规模数据的处理、算法实现)
42 0
|
算法
代码随想录算法训练营第四十一天 | LeetCode 416. 分割等和子集
代码随想录算法训练营第四十一天 | LeetCode 416. 分割等和子集
46 1
代码随想录算法训练营第四十一天 | LeetCode 416. 分割等和子集
|
6月前
|
存储 算法 程序员
【算法训练-数组 一】【数组子集】:最长无重复子数组
【算法训练-数组 一】【数组子集】:最长无重复子数组
42 0
|
算法
代码随想录算法训练营第二十七天 | LeetCode 93. 复原 IP 地址、78. 子集、90. 子集 II
代码随想录算法训练营第二十七天 | LeetCode 93. 复原 IP 地址、78. 子集、90. 子集 II
58 0
|
算法
代码随想录Day23 回溯算法 LeetCode T93 复原ip地址 LeetCode T78子集 LeetCode T90 子集II
代码随想录Day23 回溯算法 LeetCode T93 复原ip地址 LeetCode T78子集 LeetCode T90 子集II
39 0
算法训练Day41|416. 分割等和子集
算法训练Day41|416. 分割等和子集
算法训练Day28|● 93.复原IP地址 ● 78.子集 ● 90.子集II
算法训练Day28|● 93.复原IP地址 ● 78.子集 ● 90.子集II
|
存储 算法 Python
秒懂算法 | 子集树模型——0-1背包问题的回溯算法及动态规划改进
给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为W。一种物品要么全部装入背包,要么全部不装入背包,不允许部分装入。装入背包的物品的总重量不超过背包的容量。问应如何选择装入背包的物品,使得装入背包中的物品总价值最大?
645 0
秒懂算法 | 子集树模型——0-1背包问题的回溯算法及动态规划改进