字典序—lexicographical order

字典序简介

  英文名叫lexicographical order,数字可以作为特别的字符串,这种情况下,如果我们用字典序进行比较,就有可能会出现下面这种情况:
  ”100”<”1000”(加引号的目的是为了区别数字与数字串),事实上,在计算机里,我们会这么看?
  和之前一样,我们会首先比较第一个字符,这里”1”=’1’(已经可以看到区别了、在数中,数字因为位置的不同会有不同的意义,而这里,这种分别变的不一样了)。一步比较,还没有办法分辨出它们的大小,只好再比较之后的数。
  这种情况回直到最后一次尝试,第一个字符串已经空掉之前。如果硬要比较的话,空格的ascii码值是32.(Ascii码还是用两位十六进制表示比较合适)‘0’的ASCII码值是48 所以‘100’<’1000’
  例子:依次比字母, 如boat < boot < cap < card < cat < to < too< two < up.

求下一个字典序的方法

  1. 求 i = max{j | p[j – 1] < p[j]} (找最后一个正序);
  2. 求 j = max{k| p[i – 1] < p[k]} (找最后大于 p[i – 1] 的);
  3. 交换 p[i – 1] 与 p[j]得到 p[1] … p[i-2] p[j] p[i] p[i+1] … p[j-1] p[i-1]
    p[j+1] … p[n];
  4. 反转 p[j] 后面的数得到 p[1] … p[i-2] p[j] p[n] … p[j+1] p[i-1] p[j-1] …
    p[i]。

例如:设有排列(p)=2763541,按照字典式排序,它的下一个排列是什么?

  1. 2763541 (找最后一个正序35);
  2. 2763541 (找3后面比3大的最后一个数4);
  3. 2764531 (交换3,4的位置);
  4. 2764135 (把4后面的5,3,1反转)。

C++代码

void nextPermutation(vector<int>& nums) {
    int size = nums.size();
    if(size==0 || size==1)
        return;
    vector<int>::iterator p = nums.end()-1,q=nums.end()-1;
    while( p!=nums.begin() && *p<=*(p-1) )
        p--;
    if(p==nums.begin())
        reverse(nums.begin(),nums.end());
    else if(p==nums.end()-1)
        swap(*p,*(p-1));
    else{
        p--;
        while(*q<=*p)
            q--;
        swap(*p,*q);
        reverse(p+1,nums.end());
    }
}

STL中排列算法

  1. is_permutation(beg1,end1,beg2)
    is_permutation(beg1,end1,beg2,binaryPred)
    如果第二个序列的某个排序和第一个序列具有相同数目的元素,且元素都相等,则返回true。第一个版本用==比较元素,第二个版本使用给定的binaryPred。
  2. next_permutation(beg,end)
    next_permutation(beg,end,comp)
    如果序列已经是最后一个排列,则next_permutation将序列重排为最小的排序,并返回false。否则,它将输入序列转换为字典序中的下一个排列,并返回true。第一个版本使用元素的<运算比较元素,第二个版本使用给定的比较操作。
  3. prev_permutation(beg,end)
    prev_permutation(beg,end,comp)
    类似next_permutation,但将序列转换为前一个排序。如果序列已经是最小的排列,则将其重排为最大的排列,并返回false。

注意:
1. 这些算法假定序列中的元素都是唯一的。即没有两个元素的值是一样的。
2. 为了生成排序,必须即向前又向后处理排序,因此算法要求双向迭代器。

总结

  因为本人能力有限,暂时还不能深入STL源码来解析这些泛型算法,等我能够看到STL源码的时候,再来对这些算法进行详细解读。字典序排序是计算机中一个非常重要的知识,对于求解排列问题有着很好的借鉴作用,稍后我会写一些利用字典序求解问题的文章。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值