zoukankan      html  css  js  c++  java
  • stl算法:next_permutation剖析

    转载:http://blog.csdn.net/aipb2008/article/details/2227490

    其实还有一个 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。

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

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

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

    所以要想得到所有全排列

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

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

    所以

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

    才能得到123的所有排列。

  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/luotinghao/p/3413148.html
Copyright © 2011-2022 走看看