zoukankan      html  css  js  c++  java
  • stl中的next_permutation算法

    pku1731还有pku1256

    1731是对stl中的next_permutation算法的基本应用

    具体用法:http://blog.csdn.net/aipb2008/archive/2008/03/29/2227490.aspx

    在标准库算法中,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。

    其实看下代码中的运用就知道了

    pku1731:

    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    int main()
    {
    string s;
    cin>>s;
    sort(s.begin(),s.end());
    do{
    cout<<s<<endl;
    }while(next_permutation(s.begin(),s.end()));     
    return 0;
    }
    
    
    
    pku1256:主要是写一个比较函数,'A'<'a'<'B'<'b'<...<'Z'<'z'.下面的函数应该很好理解:
    #include<iostream>
    #include<algorithm>
    #include<string>
    using namespace std;
    int f(char x)//重新处理字母的大小
    {
        if('a'<=x && x<='z') return (x-'a'+1)*2;
        else return (x-'A')*2+1;
    }
    bool cmp(char x,char y)//比较函数
    {
        return f(x)<f(y);
    }
    int main()
    {
        string a;
        int t;
        scanf("%d",&t);
        while(t--)
        {
            cin>>a;
            sort(a.begin(),a.end(),cmp);
            do
            {
                cout<<a<<endl;
            }while(next_permutation(a.begin(),a.end(),cmp));
        }
        return 0;
    }
    
    
    
    
    
    
    
  • 相关阅读:
    关于JSON可能出现的错误,待更/todo
    mongoose的安装与使用(书签记录) 2017
    HTTP的学习记录3--HTTPS和HTTP
    HTTP的学习记录(二)头部
    HTTP(一)概述
    LeetCode 455. Assign Cookies
    LeetCode 453. Minimum Moves to Equal Array Elements
    LeetCode 448. Find All Numbers Disappeared in an Array
    LeetCode 447. Number of Boomerangs
    LeetCode 416. Partition Equal Subset Sum
  • 原文地址:https://www.cnblogs.com/nanke/p/2042688.html
Copyright © 2011-2022 走看看