不重复排列的生成
2016-09-26 15:30
239 查看
全排列的话比较好打。
可,当一个集合中有许多重复的元素,如{2,2,2,2,2} 如何生成不重复的排列?
易知答案只有一个。
生成不重复排列,这很实用。
思想:把重复的数字不在看做多个元素,而是看做一个元素的多个个数。
然后递归生成时,添加在答案里的是次数的减少。
正确性:如果按照以上思路,那么可以知道,每个因为我们把重复的元素当做一个元素的多个来处理,那么当一个有重复的元素递归回来时,那么这个整个重复的元素就已经完成了它的赋值给ans,例如:执行2 1 1 的时候 会再递归回2 1 0的位置,但此时就不会在添加一遍 1, 而如果是全排列的话, 2 个 1 是不同的元素,后一个1 可能和 前一个交换位置,还是2 1 1。
代码:
可,当一个集合中有许多重复的元素,如{2,2,2,2,2} 如何生成不重复的排列?
易知答案只有一个。
生成不重复排列,这很实用。
思想:把重复的数字不在看做多个元素,而是看做一个元素的多个个数。
然后递归生成时,添加在答案里的是次数的减少。
正确性:如果按照以上思路,那么可以知道,每个因为我们把重复的元素当做一个元素的多个来处理,那么当一个有重复的元素递归回来时,那么这个整个重复的元素就已经完成了它的赋值给ans,例如:执行2 1 1 的时候 会再递归回2 1 0的位置,但此时就不会在添加一遍 1, 而如果是全排列的话, 2 个 1 是不同的元素,后一个1 可能和 前一个交换位置,还是2 1 1。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <queue> using namespace std; const int MAXN = 100 + 1; int n, m; int num[MAXN], ans[MAXN]; int vis[MAXN]; void init() { memset(num,0,sizeof(num)); memset(ans,0,sizeof(ans)); memset(vis,0,sizeof(vis)); m = 0; } inline void print() { for(int i = 1; i <= n; i ++) printf("%d ", ans[i]); printf("\n"); } void dfs(int x) { if(x > n) { print(); return; } else{ for(int i = 1; i <= m; i ++) { if(vis[i] > 0) { vis[i] --; ans[x] = num[i]; printf("ans[%d] = num[%d];\n", x, i); dfs(x+1); vis[i] ++; } } } } int main() { while(cin >> n) { init(); for(int i = 1; i <= n; i ++) { int t; scanf("%d",&t); vis[i] ++; bool re = false; for(int j = 1; j <= m; j ++) if(t == num[j]) { vis[j] ++; re = true; break; } if(!re) { num[++m] = t; } } dfs(1); return 0; } return 0; } /* 3 1 1 2 1 1 2 1 2 1 2 1 1 */
相关文章推荐
- 非重复组合排列(含重复数字时,生成不重复组合排列)
- LRJ生成可重复的排列
- 递归求解几类排列组合问题(六、非重复生成全子集组合排列)
- 生成可重复的排列(递归)
- 写一个函数,参数为$n,生成一个数组,其元素为1~$n,各元素位置随机排列,不得重复
- 非重复生成全子集组合排列(含重复数字时,生成不重复全子集组合排列)
- c#生成不重复随机数
- <AJJL004>随机10个数,取出5个最小值,从小到大排列(需考虑出现重复数的情况)
- 【Java】编程随机生成不重复的大写字母数组
- JS随机生成不重复数据的代码分享
- 随机生成10个不重复的0-100的数字
- [转载]C# Random 生成不重复随机数
- 生成排列
- Android中生成库文件与移除以及导入jar包重复问题
- 随机生成6位数字,且6个数字不重复
- 枚举排列----生成可重集的排列
- 如何快速生成100万不重复的8位随机编号?
- java生成不重复的8位码
- java生成不重复的随机数
- 生成排列列