• STL 生成全排列


    在看陈硕的Linux多线程服务器编程时 ,看到生成全排列的一种方式,使用stl的next_permutation方法,正好手上有本stl源码剖析,就研究了下这个算法。

    template<class BidirectionalIterator>
    bool next_permutation(
          BidirectionalIterator first, 
          BidirectionalIterator last
    )
    {
        if(first == last)
            return false; //空序列
    
        BidirectionalIterator i = first;
        ++i;
        if(i == last)
            return false;  //一个元素,没有下一个序列了
        
        i = last;
        --i;
    
        for(;;) {
            BidirectionalIterator t = i;
            --i;
            if(*i < *t) {
                BidirectionalIterator j = last;
                while(!(*i < *--j));
    
                iter_swap(i, j);
                reverse(t, last);
                return true;
            }
            
            if(i == first) {
                reverse(first, last);  //全逆向,即为最小字典序列,如cba变为abc
                return false;
            }
        }
    }
    

      当还能生成下个排列时,返回true,如果不能在生成了,返回false。

    这是其实现方式,主要思想就是:从后往前查找相邻的迭代器 i和ii,并使得*i<*ii;再从后往前查找第一个大于i值的迭代器j,将i和j所指内容交换,并将ii到last的内容翻转。

    如果i到了begin,且(*i>=*ii),那么说明不能在生成下个排列了,返回false。

    利用这个算法生成全排列:

    #include <iostream>
    #include <algorithm>
    #include <string>
     
    using namespace std;
     
    int main()
    {
        string str;
        cin >> str;
        sort(str.begin(), str.end());
        cout << str << endl;
        while (next_permutation(str.begin(), str.end()))
        {
            cout << str << endl;
        }
        return 0;
    }

    下面自己根据此思想生成的一个方式:

    // GetAllPartition.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <VECTOR>
    #include <iostream>
    #include <iterator>
    #include <algorithm>
    using namespace std;
    
    static int num = 0;
    void getallpartition(vector<int> & v){
        vector<int>::iterator i = v.end();
        vector<int>::iterator ii;
        ostream_iterator<int> outite(cout," ");
        copy(v.begin(),v.end(),outite);
        cout<<endl;
        num++;
    
        for(;;){
            i = v.end();
            --i;
            ii = i;
            --i;
            while(!(*i < *ii) ){
                --i;
                --ii;
                if( i == v.begin() && (*i > *ii)){
                    return;
                }
            }
            if(*i < *ii){
                vector<int>::iterator j = v.end();
                while(!(*i < *--j));
                iter_swap(i,j);
                reverse(ii,v.end());
                copy(v.begin(),v.end(),outite);
                cout<<endl;
                num++;
            }
        }
    }
    
    int main(int argc, char* argv[])
    {
        int array[] = {1,2,3,4,5};
        vector<int> v(array,array+sizeof(array)/sizeof(int));
        getallpartition(v);
        cout<<num<<endl;
        return 0;
    }

    附:

    iter_swap(iteri,iterj); // 将iteri和iterj所指内容交换

    {

      T tmp = *iteri;

      *iteri = *iterj;

      *iterj = tmp;

    }

    void reverse(BidirectionlIterator first,BidirectionlIterator last);
    //双层架构,对BidirectionlIterator和RandomAccessIterator版本
    template<class BidirectionlIterator>
    inline void reverse(BidirectionlIterator first,BidirectionlIterator last){
        _reverse(first,last,iterator_category(first));
    }
    
    template<class BidirectionlIterator>
    void _reverse(BidirectionlIterator first,BidirectionlIterator last,bidirectional_iterator_tag){
        while(true){
            if(first == last || first == --last )
                return;
            else
                iter_swap(first++,last);
        }
    }
    
    template<class RandomAccessIterator>
    void _reverse(RandomAccessIterator first,RandomAccessIterator last,random_access_iterator_tag){
        while(first < last)       //Randomaccessiterator才支持<运算符,从而针对这个版本提高了效率
            iter_swap(first++,--last);
    }
  • 相关阅读:
    RabbitMQ集群
    RabbitMQ (十六) 消息队列的应用场景 (转)
    RabbitMQ (十五) 镜像集群 + HAProxy1.7.8 负载均衡
    RabbitMQ (十四) 普通集群
    RabbitMQ (十三) 集群+单机搭建(window)
    秋招_微盟_一面/二面/HR面
    秋招-腾讯云西子公司-一二面-11/16
    秋招-京东(补录)-面经-一面/二面/HR面
    秋招-腾讯补录-面经-12/10
    投递过程
  • 原文地址:https://www.cnblogs.com/xiumukediao/p/4731202.html
Copyright © 2020-2023  润新知