有重复元素的全排列

 

Description

输入n(<=10)个小些字母(可能重复),输出n个字符的全部排列。

Input

abaab

Output

1:aaabb
2:aabab
3:aabba
4:abaab
5:ababa
6:abbaa
7:baaab
8:baaba
9:babaa
10:bbaaa

#include<stdio.h>
#include<string.h>
char a[11];
char p[11];
int leap;   //标记个数
void qsort(char num[],int shangbiao,int xiabiao)  //将字符排序
{
	int i=shangbiao,j=xiabiao;
	int key=i;
	char t;
	if(shangbiao<xiabiao)
	{
		while(i<j)
		{
 			for(;j>key;j--)
			{
				if(num[j]<num[key])
				{
					t=num[j];
			    	num[j]=num[key];
			    	num[key]=t;
			     	key=j;
			    	break;
				}
			}
			i++;
			for(;i<key;i++)
			{
				if(num[i]>num[key])
				{
					t=num[i];
					num[i]=num[key];
					num[key]=t;
					key=i;
					break;
				}
			}
			j--;
		}
		qsort(num,shangbiao,key-1);
		qsort(num,key+1,xiabiao);
	}
}
void print_permutation(int n,char *p,char *a,int cur)  //重复元素排列
{
	int i,j;
	int ok=1;
	int c1=0,c2=0;
	if(cur==n)     
	{
		leap++;
		printf("%d:",leap);
		for(i=0;i<n;i++)
			printf("%c",a[i]);
		printf("\n");
	}
	else for(i=0;i<n;i++)   
	{
		if(!i||p[i]!=p[i-1])    //判断与前一个元素不相同
		{
			c1=0;c2=0;
		for(j=0;j<cur;j++)
			if(a[j]==p[i])
				c1++;
			for(j=0;j<n;j++)
				if(p[i]==p[j])
					c2++;
				if(c1<c2)
				{
					a[cur]=p[i];
					print_permutation(n,p,a,cur+1); 
				}	
		}
	}
}
int main()
{
	int n;
	gets(p);
	n=strlen(p);
	qsort(p,0,n-1);
	print_permutation(n,p,a,0);
	return 0;
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
8594 有重复元素的排列问题 时间限制:1000MS 内存限制:1000K 提交次数:1610 通过次数:656 题型: 编程题 语言: 无限制 Description 设集合R={r1,r2,...,rn}是要进行排列的n个元素,其中r1,r2,...,rn可能相同。 试着设计一个算法,列出R的所有不同排列。 即,给定n以及待排的n个可能重复元素。计算输出n个元素的所有不同排列。 输入格式 第1行是元素个数n,1<=n<=15。接下来的1行是待排列的n个元素元素中间不要加空格。 输出格式 程序运行结束时,将计算输出n个元素的所有不同排列。最后1行中的数是排列总数。 (说明: 此题,所有计算出的排列原本是无所谓顺序的。但为了容易评判,输出结果必须唯一! 现做约定:所有排列的输出顺序如课本例2-4的程序段的输出顺序,区别仅是这道题是含重复元素。) 输入样例 4 aacc 输出样例 aacc acac acca caac caca ccaa 6 提示 课本上有“递归”实现无重复元素全排列的源程序。 稍加修改即可满足此题要求。 在递归产生全排列的那段程序开始之前, 加一个判断:判断第i个元素是否在list[k,i-1]中出现过。 Permpp(char list[], int k, int m) { ...... for (int i=k; i<=m; i++) { if (Findsame(list,k,i))//判断第i个元素是否在list[k,i-1]中出现过 continue; Swap (list[k], list[i]); Permpp(list, k+1, m); Swap (list[k], list[i]); } } 作者 zhengchan ps;正确运行算法
重复元素全排列流程图如下: 1. 首先将字符串按照字典序排序,以便后续判断重复元素。 2. 从第一个元素开始,依次与后面的元素交换位置,直到最后一个元素。 3. 在交换过程中,判断是否有重复元素即将被交换,如果有则跳过这次交换。 4. 交换完成后,将当前元素与下一个元素交换位置,重复步骤3。 5. 当交换到最后一个元素时,输出当前排列结果。 举个例子,对于字符串"abb"的全排列流程如下: 1. 首先将字符串按照字典序排序,得到"abb"。 2. 从第一个元素"a"开始,依次与后面的元素交换位置,得到"bab"和"bba"。 3. 在交换过程中,判断是否有重复元素即将被交换,发现"b"即将与"b"交换,跳过这次交换。 4. 将当前元素"b"与下一个元素"b"交换位置,得到"abb"。 5. 交换到最后一个元素,输出当前排列结果"abb"。 6. 从第二个元素"b"开始,依次与后面的元素交换位置,得到"bab"和"bba"。 7. 在交换过程中,发现"b"即将与"a"交换,跳过这次交换。 8. 将当前元素"b"与下一个元素"b"交换位置,得到"abb"。 9. 交换到最后一个元素,输出当前排列结果"abb"。 10. 从第三个元素"b"开始,依次与后面的元素交换位置,得到"abb"和"abb"。 11. 在交换过程中,发现"b"即将与"b"交换,跳过这次交换。 12. 将当前元素"b"与下一个元素"b"交换位置,得到"abb"。 13. 交换到最后一个元素,输出当前排列结果"abb"。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值