重複元素排列問題
阿新 • • 發佈:2019-01-08
/* 演算法思路 : aacc四個元素的全排列,我們可以劃分為3個元素的全排列, 3個劃分為2個,到最後只剩下1個元素,就不需要排列。 我們讓每一個元素作為打頭元素,交換,然後進行遞迴,再交換。 如果該打頭元素在前面中已經有過,則忽略這種情況。 */ #include<cstdio> #include<cmath> #include<algorithm> using namespace std; /* finish函式檢查第i個元素是否在前面元素[k...i-1]中出現過 */ int finish(char list[], int k, int i) { if(i > k) { for(int j=k; j<i; j++) { if(list[j] == list[i]) //元素重複出現,返回0 { return 0; } } } return 1; } int ans = 0; //用來記錄不重排列的個數 int prem(char str[], int left, int right) { if(left == right) //陣列左右邊界相等意思為陣列中只剩下一個元素 { ans++; for(int i=0; i<=right; i++) printf("%c",str[i]); printf("\n"); } /* 陣列中還有多個元素待排列,遞迴產生排列(將元素劃分成單個元素) */ for(int i=left; i<=right; i++) { if(finish(str, left, i)) //finish檢查當前元素是否重複出現過 { swap(str[left], str[i]); //swap函式用來交換元素 prem(str, left+1, right); swap(str[left], str[i]); } } } int main() { int n; printf("請輸入排列元素的個數:\n"); scanf("%d",&n); printf("請輸入%d個元素:\n", n); char str[100003]; getchar(); ///吸收輸入元素個數後面換行符 for(int i=0; i<n; i++) { scanf("%c", &str[i]); } printf("所有不同排列為:\n"); /* 呼叫排列函式 三個引數依次為 陣列名,陣列左邊界,陣列右邊界 */ prem(str, 0, n-1); printf("不重複的排列總數為:%d\n", ans); return 0; }