字典全排序

其实字典全排序并没有想象中的那么难,基本思想方法是:复杂问题分步解决。

此处体现为:1要输出整个全排序,只需先实现“给出一串字符之后判断它的后面是否还可输出字符串,如果有的话,如何给出它的下一个字符串”的问题。

2、用递归把问题步骤1的解决过程包裹起来。

算法:

设P是1~n的一个全排列:p=p1p2......pn=p1p2......pj-1pjpj+1......pk-1pkpk+1......pn

  1)从排列的右端开始,找出第一个比右边数字小的数字的序号j(j从左端开始计算),即 j=max{i|pi<pi+1}
  2)在pj的右边的数字中,找出所有比pj大的数中最小的数字pk,即 k=max{i|pi>pj}(右边的数从右至左是递增的,因此k是所有大于pj的数字中序号最大者)
  3)对换pi,pk
  4)再将pj+1......pk-1pkpk+1......pn倒转得到排列p'=p1p2.....pj-1pjpn.....pk+1pkpk-1.....pj+1,这就是排列p的下一个排列。

       步骤1的实现为

#include<iostream>//ere
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
	char a[55];
	while(cin>>a&&a[0]!='#')
	{
		int len=strlen(a);
		int p=1;//用于标记,来判断一个字符串是否有后续的字符串 
		for(int i=0;i<len-1;i++)
		{
			if(a[i]<a[i+1]) 
			{
				p=0;
				break;
			}
		}
		if(p==1) cout<<"No Successor"<<endl;//无后续的情况
		else
		{//确定哪一位要换 
			int t;//第t位要换 
			for(int i=len;i>=1;i--)
			{
				if(a[i]>a[i-1]) 
				{
					t=i-1;
					break;
				} 
			}
			sort(a+t+1,a+len);
			for(int i=t+1;i<len;i++)
			{
				if(a[t]<a[i])//若无此步,输入ere的时候输出它的下一个字符串将是eer 
				{
					swap(a[t],a[i]); 
					break;
				}
			}
			for(int i=0;i<len;i++) cout<<a[i];
			cout<<endl;
		} 
		
	}
} 
步骤2实现:包装

#include<iostream>//ere
#include<cstring>
#include<algorithm>
using namespace std;
char a[55];
void f(char a[],int len)
{
		int p=1;//用于标记 
		for(int i=0;i<len-1;i++)
		{
			if(a[i]<a[i+1]) 
			{
				p=0;
				break;
			}
		}
		if(p==1) return;//cout<<"No Successor"<<endl;//判断无后续的情况
		else
		{//确定哪一位要换 
			int t;//第T位要换 
			for(int i=len;i>=1;i--)
			{
				if(a[i]>a[i-1]) 
				{
					t=i-1;
					break;
				}
			}
			sort(a+t+1,a+len);
			for(int i=t+1;i<len;i++)
			{
				if(a[t]<a[i])
				{
					swap(a[t],a[i]);//ere的情况 
					break;
				}
			}
			for(int i=0;i<len;i++) cout<<a[i];
			cout<<endl;
			f(a,len);
		} 
		
} 
int main()
{
	
	while(cin>>a&&a[0]!='#')
	{
		int len=strlen(a);
		sort(a,a+len);
		for(int i=0;i<len;i++) cout<<a[i];
		cout<<endl;
		f(a,len); 
	}
} 



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值