• STL 排序函数


    next_permutation
    prev_permutation

    在标准库算法中,next_permutation应用在数列操作上比较广泛.这个函数可以计算一组数据的全排列.但是怎么用,原理如何,我做了简单的剖析.

    首先查看stl中相关信息.
    函数原型:

    template<class BidirectionalIterator>
       bool next_permutation(
          BidirectionalIterator _First
          BidirectionalIterator _Last
       );
    template<class BidirectionalIterator, class BinaryPredicate>
       bool next_permutation(
          BidirectionalIterator _First, 
          BidirectionalIterator _Last,
          BinaryPredicate _Comp
       );


    两个重载函数,第二个带谓词参数_Comp,其中只带两个参数的版本,默认谓词函数为"小于".

    返回值:bool类型

    分析next_permutation函数执行过程:

    假设数列 d1,d2,d3,d4……

    范围由[first,last)标记,调用next_permutation使数列逐次增大,这个递增过程按照字典序。例如,在字母表中,abcd的下一单词排列为abdc,但是,有一关键点,如何确定这个下一排列为字典序中的next,而不是next->next->next……

    若当前调用排列到达最大字典序,比如dcba,就返回false,同时重新设置该排列为最小字典序。

    返回为true表示生成下一排列成功。下面着重分析此过程:

    根据标记从后往前比较相邻两数据,若前者小于(默认为小于)后者,标志前者为X1(位置PX)表示将被替换,再次重后往前搜索第一个不小于X1的数据,标记为X2。交换X1,X2,然后把[PX+1,last)标记范围置逆。完成。

    要点:为什么这样就可以保证得到的为最小递增。

    从位置first开始原数列与新数列不同的数据位置是PX,并且新数据为X2。[PX+1,last)总是递减的,[first,PX)没有改变,因为X2>X1,所以不管X2后面怎样排列都比原数列大,反转[PX+1,last)使此子数列(递增)为最小。从而保证的新数列为原数列的字典序排列next。

    明白了这个原理后,看下面例子:

    i

    1 nt main(){
    2  int a[] = {3,1,2};
    3 do{
    4      cout << a[0] << " " << a[1] << " " << a[2] << endl;
    5 }
    6  while (next_permutation(a,a+3));
    7  return 0;
    8 }

    输出:312/321         因为原数列不是从最小字典排列开始。

    所以要想得到所有全排列

     int a[] = {3,1,2};   change to  int a[] = {1,2,3};

    另外,库中另一函数prev_permutation与next_permutation相反,由原排列得到字典序中上一次最近排列。

    所以

    1 int main(){
    2  int a[] = {3,2,1};
    3 do{
    4      cout << a[0] << " " << a[1] << " " << a[2] << endl;
    5 }
    6  while (prev_permutation(a,a+3));
    7  return 0;
    8 }

    才能得到123的所有排列。

    附POJ 1731 Orders

     1 #include <iostream>
     2 #include <algorithm>
     3 #include <string.h>
     4 
     5 using namespace std;
     6 
     7 int cmp(const void*a,const void*b)
     8 {
     9     return *(char*)a-*(char*)b;
    10 }
    11 
    12 int main()
    13 {
    14     char s[200];
    15     cin>>s;
    16     int len=strlen(s);
    17 
    18     qsort(s,len,sizeof(s[0]),cmp);
    19 
    20     cout<<s<<endl;
    21 
    22     while(next_permutation(s,s+len))
    23         cout<<s<<endl;
    24 
    25 
    26     return 0;
    27 }
  • 相关阅读:
    mustache.js 使用
    iscroll4 input textarea不能获得焦点问题
    object-fit?
    window.open()被拦截问题
    JSONP
    mouseenter和mouseover的区别
    前端页面卡顿-代码优化
    如何设置html中img宽高相同-css
    iscroll使用之页面卡顿问题
    iScroll的简单使用
  • 原文地址:https://www.cnblogs.com/CKboss/p/3014996.html
Copyright © 2020-2023  润新知