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;}