非重复生成全子集组合排列(含重复数字时,生成不重复全子集组合排列)
来源:互联网 发布:淘宝先行垫付吗 编辑:程序博客网 时间:2024/05/04 09:34
Sample Input
4
1 2 2 3
Sample Output
1
12
122
1223
123
13
2
22
223
23
3
如果采用上篇文章的程序(处理不含重复数),运行的结果是:
以上均为重复数据,上标表示在原数据中使用的是重复数据的第几个数据,这就多出来好几种。
出现这种情况的原因是:在mat中存有重复的数据,在赋值的时候,仍然把这些数据取出直接赋值到数组result中。
要避免这种情况,就引入两个数组mat和 used数组:
mat数组:一个存放不重复数据的数据
used数组:存放每个数据出现的次数
在递归过程中,使用mat为数组result直接赋值。在赋值时,由于使用不重复数据的数据mat数组直接对其进行赋值,这就避免出现121 和122情况了。
但是,使用这种存储的方式,就会把应该出现的数据也给扼杀了,如1223。这里的做法是 递归传值的时候,mat数组中每一位数据可以重复传一次,检测是不是重复出现过。
具体表现是solve(cur_totalVar+1,i)中的i,即下一次取数的下标是i,而i是本次递归刚刚处理过下标i的位置,使用这样的方法,就可以连续的检测某一个数是不是重复出现了,
进而可以连续的读取。
#include <iostream>using namespace std;const int len=10;int n;int num;//不重复的实际个数int mat[len];int result[len];int used[len];void push(int varNum);void solve(int cur_totalVar,int nextVar);int main(){cin>>n;num=0;int var;for (int i=0;i<n;i++){cin>>var;push(var);}solve(0,0);system("pause");return 1;}/*---------------------- 操作的目的:生成一个数据全不重复的数组,并记录每个数出现的次数操作结果:num记录不重复数的个数(mat数组中数据的长度)mat数组存储不重复的数据used数组统计对应mat数组位置数据的出现次数函数参数: varNum:存储刚刚输入的数据,用来检测是不是重复的数据------------------------*/ void push(int varNum){for (int i=0;i<num;i++){if (mat[i]==varNum){used[i]++;return;}}mat[num]=varNum;used[num]++;num++;}/*---------------------- 操作的目的:生成全子集组合排列(含重复数据)初始条件:num记录不重复数的个数(mat数组中数据的长度)mat数组存储不重复的数据used数组统计对应mat数组位置数据的出现次数操作结果:输出全部子集函数参数: cur_totalVar:针对输出数组result,表示现在要存放数据的位置,之后也控制着输出 nextVar:针对原存储数组mat,表示下一个要读取数据的位置 ------------------------*/ void solve(int cur_totalVar,int nextVar){for (int i=0;i<cur_totalVar;i++){cout<<result[i];}cout<<endl;for (int i=nextVar;i<num;i++){if (used[i]){result[cur_totalVar]=mat[i];used[i]--;solve(cur_totalVar+1,i);/*这里的参数i表示:数组mat中下一个要处理的数是本次函数刚刚处理过的,这里还要在检查一遍,就是为了处理有数据重复的情况,如果数据不重复,就使用i+1*/used[i]++;//恢复现场}}}/*算法的思想:函数思想:使用for循环遍历原存储数据的数组mat,边遍历边对输出数组result赋值,同时进行递归. 为了处理重复的数据,就让mat数组存储不重复的数据,在为数组result赋值时,使用这个不重复的数组进行赋值,但是要处理重复的数据的话,在递归传递参数的时候,把刚刚处理过的数据再传进去一遍,在进行一下处理,检测是不是有重复,若重复,就可以再使用一次。但是这里的重复使用时不会出现重复的数据的,具体可以写一下递归的过程分析一下。其中还是数组mat起了关键作用。忽略递归,从for循环来看,存储数组中要存放数据的位置cur_totalVar是固定的,使用for循环对result进行赋值,这样就可以让输出数组中同一个位置有多个变化的变量。这时,在看递归,当结果数组的cur_totalVar位置已经赋值成功后,之后应该是对结果数组result的cur_totalVar+1的位置使用原数组mat的i+1位置的数据进行赋值(第i个数据已经赋过值了)--这里先不考虑重复数据。 如果考虑重复的位数,当然应该是传入mat中第i位,看是不是重复。*/
- 非重复生成全子集组合排列(含重复数字时,生成不重复全子集组合排列)
- 非重复组合排列(含重复数字时,生成不重复组合排列)
- 递归求解几类排列组合问题(六、非重复生成全子集组合排列)
- 递归学习_组合_生成全子集组合排列(不含空集)
- 生成全排列、非全排列、组合
- 全排列与子集生成
- 子集生成+stl全排列
- 全排列不重复
- 递归求解几类排列组合问题(五、生成全子集组合排列)
- 全排列的java实现(含重复数字)
- 剑指offer-全排列(含重复数字)
- C语言算法—(生成子集的升级)生成数据的全部组合(含重复数字)(类似建立树的回溯法)
- 非重复全排列算法
- 全排列 不重复算法
- 不重复排列的生成
- 123456数字组合排列(5个数组合不能重复)
- 全排列算法:不含重复元素,包含重复元素,字母序排列
- 含重复元素的全排列
- 各行各业年初奖
- Java正则表达式应用总结
- Servlet基础_0600_UserBean
- php关联表合并成临时表— left join 用法详解
- IE 6 图片<img/> 写入html ,图片不显示问题
- 非重复生成全子集组合排列(含重复数字时,生成不重复全子集组合排列)
- xml元素标记名称规范
- 教你如何看清一个人的实质 很靠谱的
- Json
- NFC的普及还要多长时间?
- [Info]三大科技文献检索系统
- 堆(heap)和栈(stack)有什么区别?
- java学习笔记(十三)
- 淘宝笔试归来