1. 程式人生 > >重複元素排列問題

重複元素排列問題

/*
演算法思路 :
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;
}