字典序算法

来源:互联网 发布:淘宝谁家假发好 编辑:程序博客网 时间:2024/05/27 03:28

字典序算法

我们都知道字典中的单词是如何排列的,即首先比较第一个,如果哪一个较小那么这个单词就排在前面,如果相等,那么比较第二个,依此类推。在c++的STL中也有一个类似的算法,即next_permutation,它按照字典一样的排序算法,计算出一个序列的下一个序列是什么,例如32456983的下一个就是32458369,下面来详细说明一下原理,步骤和解释。

原理:

我们要找下一个序列,就是找到比当前序列所有大的序列中最小的一个,毫无疑问,我们就要尽量向后找可以变大的元素,如果存在ai < aj (i < j),那么一定能找到下一个序列,那么如何确定这个需要开始起变化的元素呢?就是要找到最后一个这样的ai,这样才能得到最小的一个。找到之后该如何操作呢?我们在后面找到最小的比ai大的元素和ai交换,然后在位置i后面的元素从小到大排列,这个新的的序列就是按字典序的下一个序列。

步骤:

  1. 找到最后一个元素,这个元素满足在它的后面存在比它大的元素的条件,记为ai。
  2. 然后找到ai后面最后一个比ai大的元素aj。
  3. 接着,交换ai和aj的值,然后将ai和aj之间的部分翻转。

解释:

第一步已经在原理中说明了。第二步为什么要找最后一个比ai大的元素呢?其实这句话就是指的比ai大的元素中最小的一个,因为第一个步骤保证了aj前面不会有比它小的元素,不然ai也不会称为第一步确定的元素,所以最后一个就是最小的一个,二不说最小的一个是为了代码实现更易懂。而aj之后的元素是比ai小的,所以ai和aj交换位置以后,在位置i后面的元素是从小到大排列的,然后进行第三部倒转,就能得到下一个序列。

代码例子:

bool my_next_permutation(char* p, int num){    int i;    for (i = num - 2; i >= 0; --i) {        if (p[i] < p[i + 1])            break;    }    if (i == 0)        return false;    int j = i + 1;    while (p[j] > p[i])        ++j;    swap(p[i], p[j - 1]);    reverse(p + i + 1, p + num);    return true;}
0 0
原创粉丝点击