字典序法求一个数组的全排列4

全排列算法,大致来讲有四种字典序法,递增进位制数法,递减进位制数法,邻位对换法,这里讲一下字典序方法。

首先看什么叫字典序,顾名思义就是按照字典的顺序(a-z, 1-9)。以字典序为基础,我们可以得出任意两个数字串的大小。

比如字符串“abcdg”和“abcfdg”,我们从左到右比较每一个字符的大小,发现第四个字符‘d’和‘f’,‘f’的字典序更大,因此前一个字符串比后一个字符串的字典序要小。

因此,对与“abc”,他的字典序最大的值是“cba”,最小的值是“abc”,其他的排序的字典序都在他们之间。因此,求一个串的全排列,我们只需要从串的字典序最小的排列开始,求出当前字典序的下一个字典序排序,直到字典序的值最大。我们就求出了所有的全排列!!!

对于,“abc”,我们从最小字典序“abc”开始,依次有:

abc(最小)     acb   bac   bca    cab     cba(最大)

那么对于当前的序列我们如何求,他的下一个字典序呢.(所谓一个的下一个就是这一个与下一个之间没有其他的)

一般算法可以分为三步:

对于串 5,8,7,9,3,6,4,2,1

1.我们从右向左找到第一个a[i],满足a【i】<a【i+1】,这里a【i】=3;

2.我们从a【i】开始向后,找最后一个a【j】>=a【i】,这里a【j】=4;

3.交换a【i】,和a【j】,有串 5,8,7,9,4,6,3,2,1

反转i位置后所有的元素5,8,7,9,41,2,3,6,得到下一个全排列

//arr是要排列的数组,n是数组的长度,当不存在下一个排列时返回false;
bool NextPermutation(int * arr,int n)
{
	int i,j,k;
	for(i=n-1;i>0;i--)//从尾巴开始找第一个arr【i】>arr【i-1】
		if(arr[i]>arr[i-1]) 
			break;
	if(i==0) //如果没找到,则输入的已经是最大字典序
		return false;
	i--;
	for(j=i+1;j<n;j++)//从i之后,开始找第一个不大于,a【i】的数,
		if(arr[i]>=arr[j])//注意这里是不大于!!!
			break;
	j--;
	swap(arr[i],arr[j]);
	j=n-1;i=i+1;
	while(i<j)
		swap(arr[i++],arr[j--]);
	return true;
}

字典序的不但能解决排列问题,也能解决组合问题,比如:从5个球中取三个,我们只要对0,0,0,1,1这样一个数组按照字典序进行全排列,就能遍历出所有组合。!!!!!当然,我们可以用stl里的next_permutation函数实现全排列!!!


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值