子集生成 增量构造法 位向量法 二进制法
增量构造法
参考
//此算法仅仅是输出下标,实际应用应输入另一个数组来进行存储数据
//这三种方式,为了理解这个花费了最长的时间,太纠结于细节了,刘汝佳写的不是特别清楚
//这三种方式的话,都可以理解为输出0 - n-1的这n个数字的子集
//疑问就是我的数列并不是单纯的0 - n-1, 如果不是这种情况,那该怎么办,
//所以说,可以定义一个数据数组,这三种方式所直接输出的集合就是数据数组的下标集合
//说到这里就不难理解下文的代码了
//A数组是下标数组,每次输出的是下标集合
#include<iostream>
#include<cstdio>
#include<cstring>using namespace std;void print_subset(int n, int *A, int cur) {//cur是当前A数组的位置for(int i = 0; i < cur; ++i) {printf("%d ", A[i]);//如果有数据数组, 就写成data[A[i]],此处不再赘述}printf("\n");int s = cur ? A[cur - 1] + 1 : 0;//这一句是比较难以理解,尤其是A[cur-1] + 1这里,看了好久才搞明白//当cur等于0的时候,这是第一次进入函数,所以选取的集合下标元素为0就可以了//cur不等于0的时候,即cur前面还有下标元素,为了得到全部的子集,所以这里不能漏掉,便从最小的那一个选择//那为什么A[cur-1]+1就是最小的下标呢,刚刚输出的最后一个下标就是A[cur-1],所以这一个下标+1,即还未选择过的最小下标//然后就是从当前最小的还未选择过的下标作为下一个下标集合的首元素开始选取//直到n-1的下标位置,每一次选取首下标之后都开始递归for(int i = s; i < n; ++i) {A[cur] = i;print_subset(n, A, cur + 1);}
}int main() {int n;int A[10];//该数组存放的是数据数组的下标,为了简单,并没有定义数据数组,数据数组在输出的时候才用得上while(scanf("%d", &n) == 1) {print_subset(n, A, 0);}return 0;
}
位向量法
//此算法仅仅是输出下标,实际应用应输入另一个数组来进行存储数据
//这个比较好理解,就相当于枚举,跟二进制有点相似, 这个使用数组表示,二进制是使用数字的二进制位置表示
#include<iostream>
#include<cstring>
#include<cstdio>using namespace std;void print_subset(int n, int *B, int cur) {if(cur == n) { //已经枚举完一种状态,输出for(int i = 0; i < n; ++i) {if(B[i]) {printf("%d ", i);}}printf("\n");return;}B[cur] = 1; //该元素在下一个将要枚举的集合中print_subset(n, B, cur + 1);B[cur] = 0; //该元素不在下一个将要枚举的集合中print_subset(n, B, cur + 1);
}int main() {int n, B[10];while(cin >> n) {print_subset(n, B, 0);}return 0;
}
二进制法
//此算法仅仅是输出下标,实际应用应输入另一个数组来进行存储数据
//原理:用数字的二进制位表示状态,二进制从右到左的第几个位置 表示数组元素的下标#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>using namespace std;void print_subset(int n, int s) {//s代表的是当前二进制数表示的状态for(int i = 0; i < n; ++i) {if(s & 1 << i) {//1左移几位就代表第i个二进制位为1,其他位为0,与状态进行&运算,如果此状态包含该数字,就输出printf("%d ", i);}}printf("\n");
}int main() {int n;while(scanf("%d", &n) == 1) {//一共n个数字,所以其全集有2^n个二进制1,所对应的十进制数字就是2^n - 1//我们要做的就是枚举出来每一种状态,1 右移 n 位,所得的十进制数字就是2^nfor(int i = 0; i < (1 << n) ; ++i) { //i表示集合元素的状态,根据该状态打印出当前集合print_subset(n, i);}}return 0;
}
子集生成 增量构造法 位向量法 二进制法相关推荐
- 子集生成-增量构造法||位向量法
#include<bits/stdc++.h> using namespace std; int arr[25]; void print_subset(int n,int* A,int c ...
- 子集生成(二进制法,逐步生成,递归增量)
子集生成的三种方法 二进制法 1.不算空集,共有2^n-1个子集 2.对应二进制数的第N为1,则将A[N]选中,否则不选 逐步生成法 对每一个元素进行处理,每一个元素都可以被选中或者不选中 递归增量构 ...
- 生成子集——二进制法
我的个人博客:逐步前行STEP #用二进制位的0和1表示集合中是否存在该元素 要生成0n的子集,先生成0n的二进制序列,这些序列的0.1位正好可以对应一个子集中全集在该位置上的元素是否存在,将其作为子 ...
- 子集生成 --二进制法
用二进制表示{0,1,2,3...n-1}的子集s:从右往左第i位表示元素i是否在集合s中.图2表示10100110是如何展示了集合{1,2,5,7}的. 注意:为了方便,最右边的为总是对应元素0,而 ...
- 子集生成算法 之 位向量法和增量构造法
什么是子集生成? 算法竞赛经典入门中的解释:给定一个集合,枚举所有的可能的子集. 位向量法 1.什么是位向量法? 通过构造一个标记向量pd[i],而不直接构造存放题目数据的子集A. 当pd[i]==t ...
- 子集生成的两种方法 (增量构造法 和 位向量法)
该算法来自--刘汝佳的算法竞赛入门经典.书中介绍了两种算法的核心代码,但却没有逐过程详细解说,另初学者看文字时很难看懂 遇到问题,是先要直接研究问题的细节呢还是先把问题搞清楚? 我认为绝对应该先学习如 ...
- 计算几何入门 1.3:凸包的构造——增量构造法
极点法和极边法的复杂度分别为O(n^4)和O(n^3),当点集S的规模稍大时就难以适用了.为了满足实际需要必须寻找更高效的算法来构造凸包. 一.减治 在引入新算法之前首先来回顾一下经典的算法思想:减治 ...
- lr1分析器c语言实验报告怎么写,编译原理课程的设计构造LR分析法语法分析器.doc...
编译原理课程的设计构造LR分析法语法分析器 太 原 学 院 课程设计报告书 课程名称 设计题目 构造LR(0)分析法语法分析器 专业班级 学 号 姓 名 指导教师 2016年 12 月 15日 目 录 ...
- Java解决Hash(散列)冲突的四种方法--开放地址法(线性探测,二次探测,伪随机探测)、链地址法、再哈希、建立公共溢出区
Java解决Hash(散列)冲突的四种方法--开放地址法(线性探测,二次探测,伪随机探测).链地址法.再哈希.建立公共溢出区 参考文章: (1)Java解决Hash(散列)冲突的四种方法--开放地址法 ...
最新文章
- 配电技术——配电线路系统电气设备详解
- 使用FluentValidation来进行数据有效性验证
- SAP数据分析图形相关内容
- Python与Golang协程异同
- 从 wiscKey 看 LSMtree 的不足
- 【python】Macbook的Anaconda查看、创建和管理python环境
- 类的扩充 js中面向对象的技术
- 君正4750开发板使用日记2-Linux环境搭建与内核编译
- TouchSlide - 大话主席
- LINUX编译:通过prefix把编译结果输出到指定位置
- Jsckson 实现 java 对象与 JSONObject 和 JSONArray 互转
- RF射频信号,高速信号能将电源平面作为参考平面吗?
- 网页连接opc服务器,远程连接opc服务器
- python逆序输出_python倒序输出
- 解决报错:soundfile.LibsndfileError: Error opening ‘.wav‘: File contains data in an unknown format.
- 如何看待 AI 方向 PhD 申请竞争过于激烈的现象?
- Centos7 安装Nginx+vsftp
- 临汾市互联网+政务服务平台
- Android:URLEncoder空格被转码为“+”号
- GBT 1.1-2020和GBT 1.2-2020最新国标PDF下载