字典序 解释:
按照字典中的排序来排序一串序列集合
(即对集合的全排列进行排序):***升序在前,降序在后***——全升到全降
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;
}
}
}
}