c++ 实现部分排序,待改进

C++代码(4)排列与组合
#include <assert.h>
#include <iostream>
#include <algorithm>
using namespace std;

template<typename T>
void Perm(T* pT, int n, int m)
{
    if (n == m)
    {
        for (int i=0; i<m; i++)
            cout << pT[i] << " ";
        cout << endl;
        return;
    }
    else
    {
        for (int i=m; i<n; i++)
        {
            swap(pT[m], pT[i]);
            Perm(pT, n, m+1);
            swap(pT[m], pT[i]);
        }
    }
}

class Permutation
{
public:
    enum {MAX_SIZE = 10};
    Permutation(int nTotal, int nPart)
    {
        assert(0 < nTotal && nTotal < MAX_SIZE);
        assert(0 < nPart && nPart <= nTotal);
        m_nPart = (char)nPart;
        m_nTotal = (char)nTotal;
        for (char i=0; i<m_nTotal; i++)
            m_Indexs[i] = i;
    }
    
public:
    bool ToNext();

    char operator[] (int n)const
    {
        assert(0 <= n && n <= m_nTotal); // >??? 和原文不一致,需确认
        return m_Indexs[n];
    }

private:
    char m_Indexs[MAX_SIZE];
    char m_nPart;
    char m_nTotal;
};

bool Permutation::ToNext()
{
    if (m_nPart == m_nTotal)
    {
        // 为全排列
        char nReverse = m_nTotal-1;  
        while (nReverse > 0 && m_Indexs[nReverse]<m_Indexs[nReverse-1])      
           nReverse--;    // 寻找第一个要交换的元素   
        if (nReverse == 0)    // 找不到,表示全排已经完成   
           return false;  
      
        char nSwap = m_nTotal - 1;  
        while (m_Indexs[nSwap] < m_Indexs[nReverse-1])  
            nSwap--;    // 寻找第二个元素   
        swap(m_Indexs[nReverse-1], m_Indexs[nSwap]);    // 开始交换   
        reverse(m_Indexs+nReverse, m_Indexs+m_nTotal);    // 逆顺   

        return true;
    }
    char nToSwap = m_nPart-1;
    char nLeft = m_nTotal - 1;
    if (m_Indexs[nLeft] > m_Indexs[nToSwap])    // 只改变尾数
    {
        while (nLeft > nToSwap && m_Indexs[nLeft]>m_Indexs[nToSwap])
            nLeft--;    
        nLeft++;
        swap(m_Indexs[nToSwap], m_Indexs[nLeft]);    
        return true;
    }
    while (nToSwap > 0 && m_Indexs[nToSwap]<m_Indexs[nToSwap-1] && m_Indexs[nToSwap]>m_Indexs[nLeft])
        nToSwap--;
    if (nToSwap == 0)    // 部分排列业已完成
        return false;
    nToSwap--;    // 已确定这个位置要参与交换了
    if (m_Indexs[nToSwap] > m_Indexs[nLeft]) // 同参与部分排列的元素交换
    {
        char nReplace = m_nPart - 1;
        while (m_Indexs[nReplace] < m_Indexs[nToSwap])
            nReplace--;
        swap(m_Indexs[nToSwap], m_Indexs[nReplace]);
    }
    else    // 同未参与部分排列的元素交换
    {
        while (nLeft >= m_nPart && m_Indexs[nLeft]>m_Indexs[nToSwap])
            nLeft--;    
        nLeft++;
        swap(m_Indexs[nToSwap], m_Indexs[nLeft]);        
    }
    sort(m_Indexs+nToSwap+1, m_Indexs+m_nTotal);// 后面为剩下来的最小排列数
    return true;
}

int main()
{
    const int N = 3, M = 3;
    Permutation perm(N, M);
    const char* sTests[N] = {"aaa", "bbb", "ccc"};
    do
    {
        for (int i=0; i<N; i++)
            cout << sTests[perm[i]] << " ";
        cout << endl;
    }while(perm.ToNext());
    return 0;
}


 

你可能感兴趣的:(c++ 实现部分排序,待改进)