排列与组合生成类

// Copyright (c) 

// All rights reserved.

//

//Describe : Premutation And Combination generater

//Author   : Qing

//Date     : 2015-01-19



#ifndef __PREMUTATION_COMBINATION_H__

#define __PREMUTATION_COMBINATION_H__



#include <bitset>

#include <vector>

#include <algorithm>



namespace Qing

{

    template<typename T, unsigned int ElementCount>

    class PermutationCombination

    {

    public:



        PermutationCombination(void) {}

        ~PermutationCombination(void){}



        bool GetCombination(const std::vector<T> &SourceVector, int CombinationElementCount, std::vector<std::vector<T> > &ResultVector);

        bool GetPermutation(const std::vector<T> &SourceVector, int PermutationElementCount, std::vector<std::vector<T> > &ResultVector);



    private:



        bool AdjustPosition(std::bitset<ElementCount> &FlagArray, unsigned int SourceVectorElementCount);

    };



    template<typename T, unsigned int ElementCount>

    bool PermutationCombination<T,ElementCount>::GetCombination(const std::vector<T> &SourceVector, int CombinationElementCount, std::vector<std::vector<T> >& ResultVector)

    {

        if(SourceVector.size() <= 0 || CombinationElementCount <= 0 || CombinationElementCount > static_cast<int>(SourceVector.size()))

        {

            return false;

        }



        std::bitset<ElementCount> FlagArray;

        for(int Index = 0; Index < CombinationElementCount; Index++)

        {

            FlagArray.set(Index);

        }



        do

        {

            ResultVector.push_back(std::vector<T>(CombinationElementCount, T()));

            std::vector<T> &TempArray = ResultVector[ResultVector.size()-1];



            std::vector<T>::size_type TempIndex = 0;

            for(std::size_t BitSetIndex = 0; BitSetIndex < FlagArray.size(); BitSetIndex++)

            {

                if(FlagArray[BitSetIndex])

                {

                    TempArray[TempIndex] = SourceVector[BitSetIndex];

                    if(++TempIndex == CombinationElementCount)

                    {

                        break;

                    }

                }

            }

        }

        while(AdjustPosition(FlagArray, SourceVector.size()));



        return true;

    }



    template<typename T, unsigned int ElementCount>

    bool PermutationCombination<T,ElementCount>::GetPermutation(const std::vector<T> &SourceVector, int PermutationElementCount, std::vector<std::vector<T> >& ResultVector)

    {

        if(SourceVector.size() <= 0 || PermutationElementCount <= 0 || PermutationElementCount > static_cast<int>(SourceVector.size()))

        {

            return false;

        }



        std::bitset<ElementCount> FlagArray;

        for(int Index = 0; Index < PermutationElementCount; Index++)

        {

            FlagArray.set(Index);

        }



        std::vector<T> TempArray(PermutationElementCount,T());



        do

        {

            std::vector<T>::size_type TempIndex = 0;

            for(std::size_t BitSetIndex = 0; BitSetIndex < FlagArray.size(); BitSetIndex++)

            {

                if(FlagArray[BitSetIndex])

                {

                    TempArray[TempIndex] = SourceVector[BitSetIndex];

                    if(++TempIndex == PermutationElementCount)

                    {

                        do

                        {

                            ResultVector.push_back(TempArray);

                        }

                        while (next_permutation(TempArray.begin(), TempArray.end()));



                        break;

                    }

                }

            }

        }

        while(AdjustPosition(FlagArray, SourceVector.size()));



        return true;

    }



    //*********************** 0-1 exchange algorithm ************************

    //  example : C(5,3)

    //      1   1   1   0   0

    //      1   1   0   1   0

    //      1   0   1   1   0

    //      0   1   1   1   0

    //      1   1   0   0   1

    //      1   0   1   0   1

    //      0   1   1   0   1

    //      1   0   0   1   1

    //      0   1   0   1   1

    //      0   0   1   1   1

    //*********************** 0-1 exchange algorithm ************************

    template<typename T, unsigned int ElementCount>

    bool PermutationCombination<T,ElementCount>::AdjustPosition(std::bitset<ElementCount> &FlagArray, unsigned int SourceVectorElementCount)

    {

        SourceVectorElementCount -= 1;

        for(unsigned int i = 0; i < SourceVectorElementCount; i++)

        {

            if(FlagArray[i] && !FlagArray[i+1])

            {

                FlagArray.reset(i);

                FlagArray.set(i + 1);



                if(!FlagArray[0] && i != 0)

                {

                    int TrueCount = 0;

                    for(unsigned int j = 0; j < i; j++)

                    {

                        if(FlagArray[j])

                        {

                            ++TrueCount;

                        }



                        FlagArray.reset(j);

                    }



                    for(int k = 0; k < TrueCount; k++)

                    {

                        FlagArray.set(k);

                    }

                }



                return true;

            }

        }



        return false;

    }

}



#endif

 

你可能感兴趣的:(生成)