1.問題描述
設集合R={r1,r2,...,rn}是要進行排列的n個元素,其中r1,r2,...,rn可能相同。 試着設計一個算法,列出R的所有不同排列。 即,給定n以及待排的n個可能重複的元素。計算輸出n個元素的所有不同排列。
2.算法設計
給定n及待排列的n個元素,計算出這n個元素的所有不同排列。
3.數據輸入
第1行是元素個數n,1<=n<=500。接下來的1行是待排列的n個元素
4.結果輸出
程序運行結束時,將計算輸出n個元素的所有不同排列。最後1行中的數是排列總數。
5.輸入樣例
輸入:
4
aacc
輸出:
aacc
acac
acca
caac
caca
ccaa
6
算法思路 :
1)aacc四個元素的全排列,我們可以劃分爲3個元素的全排列,3個劃分爲2個,到最後只剩下1個元素,就不需要排列。
2)我們讓每一個元素作爲打頭元素,交換,然後進行遞歸,再交換。
3)如果該打頭元素在前面中已經有過,則忽略這種情況。
代碼如下:
-
#include<stdio.h> #include<string.h> int count=0; void swap(char &a,char &b) { char temp; temp=a; a=b; b=temp; } int finish(char list[],int k,int i) {//第i個元素是否在前面元素[k...i-1]中出現過 if(i>k) { for(int j=k;j<i;j++) if(list[j]==list[i]) return 0; } return 1; } void perm(char list[],int k,int m) { if(k==m) //當只剩下一個元素時則輸出 { count++; for(int i=0;i<=m;i++) printf("%c",list[i]); putchar('\n'); } for(int i=k;i<=m;i++) //還有多個元素待排列,遞歸產生排列 { if(finish(list,k,i)) { swap(list[k],list[i]); perm(list,k+1,m); swap(list[k],list[i]); } } } int main() { int i,n; printf("請輸入元素個數:\n"); scanf("%d",&n); printf("請輸入待排列的元素:\n"); getchar(); char *a=new char[n]; for(i=0;i<n;i++) scanf("%c",&a[i]); printf("所有不同排列爲:\n"); perm(a,0,n-1); printf("排列總數爲:%d\n",count); return 0; }