排列与组合生成类

// 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
原文地址:https://www.cnblogs.com/zwq1011/p/4525378.html