算法入门经典-第七章 例题7-2-2 可重集的排列

补充:如果某步骤的解可以由多个步骤得到,而每个步骤都有若干种选择,这些候选方式可能依赖于之前的选择,

且可以用递归枚举法实现,则它的工作方式可以用解答树来描述

可重:如果问题变成输入数组p,并按字典序输出数组A个元素的所有全排列,则需要修改代码集的全排列

#include<cstdio>
#include<algorithm>
using namespace std;

int P[100], A[100];

// 输出数组P中元素的全排列。数组P中可能有重复元素
void print_permutation(int n, int* P, int* A, int cur) {
  if(cur == n) {
    for(int i = 0; i < n; i++) printf("%d ", A[i]);
    printf("
");
//printf("cur=%d ",cur); }
else for(int i = 0; i < n; i++) //p[i] == p[i-1]的话,那么p[i]这个数只考虑p[i-1]的就行 //i == 0 时 那么必定要取 因为没有比它更前的可以考虑 if(!i || P[i] != P[i-1]) { int c1 = 0, c2 = 0; //A是已经填进去的, P是还没有填的 //用c1 c2统计已经填进去的个数和全部, 如果c1 < c2说明有没填进去的 for(int j = 0; j < cur; j++) if(A[j] == P[i]) c1++; for(int j = 0; j < n; j++) if(P[i] == P[j]) c2++; // printf("i=%d cur=%d c1=%d c2=%d ", i, cur,c1,c2); if(c1 < c2) { A[cur] = P[i]; print_permutation(n, P, A, cur+1); } } } int main() { int i, n; scanf("%d", &n); for(i = 0; i < n; i++) scanf("%d", &P[i]); sort(P, P+n); print_permutation(n, P, A, 0); return 0; }

 

测试

原文地址:https://www.cnblogs.com/is-Tina/p/7475951.html