有重複元素的排列問題

 

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.輸入樣例
        輸入:

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;
    } 
    

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章