【学习】字典序

字典序 解释:
按照字典中的排序来排序一串序列集合
(即对集合的全排列进行排序):***升序在前,降序在后***——全升到全降
abc < acb < bac < bca < cab < cba  
逆字典序
逆序排列 :***降序在前,升序在后***

例子来源
例如:
对于2763541
找出字典序的下一个排列。

2763541 (从右至左首先出现的是35,3<5);
2763541 (在3的位置之后从右至左找到第一个比3大的数4);
2764531 (交换3,4的位置);
2764135 (把原来3的位置现在4位置后面的数值5,3,1反转)。

解: 就是找到比2763541大的但是同时在1、2、3、4、5、6、7所有排列中比2763541大的程度中最小的一个。

为了找到大的程度最小的,一般保证前面的数字位置不调换,优先调换后面数字的排列。

首先注意到541是按照降序排列(为什么是降序,只要按照字典序算法,后面就一直这样)。(不然的话就应该排在当前序列之前了)

如果我们想通过调换541的位置显然不行,5>4>1,当我们遇到3时,发现有戏,因为在3的后面有比3大的数字,我们把3往后调,把一个大的数字往前调就能把排列整体变大。那么3后面有5和4,我们选择哪一个的,显然是4,因为其增大程度较小。有因为3<4,所以调换位置后后面数字依然是降序,我们只要将其调成升序即可变成最小。

按字典序打印全排列:来源链接
/*
 * 打印n的全排列!
 */
 
#include <iostream>
#include <cstring>
using namespace std;
 
#define MAX 200
 
 
void print_permutation(int, bool *, int *, int);
 
int main() 
{
	int n;
	bool isPrint[MAX];
	int v[MAX];
	memset(isPrint, 0, sizeof(isPrint));
	memset(v, 0, sizeof(v));
	cin >> n;
	print_permutation(0, isPrint, v, n);
 
	return 0;
}
 
void print_permutation(int num, bool *isPrint, int *v, int n)
{
	if (num == n)
	{
		for (int i = 0; i < n; ++ i)
		{
			cout << v[i] << " ";
		}
		cout << endl;
		return ;
	}
		
	else
	{
		for (int i = 0; i < n; ++ i)
		{
			if ( !isPrint[i] )
			{
				isPrint[i] = 1;
				v[num] = i + 1;
				// 打印第num+1个数
				print_permutation(num + 1, isPrint, v, n);
				isPrint[i] = 0;
			}
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值