排列組合問題匯總

來源:互聯網
上載者:User

問題一 列印出一個集合中的元素的所有可能的組合.

思路如下:元素個數為n,可以用一個n位位元的每一個bit對應集合中的每一個元素。任取一個n位位元即能夠表示對該集合中元素的一種選擇方案。規則如下:某bit為1,表示選中該元素,為0表示不選中該元素。則從1,累加到(2^n) - 1,即可得到所有組合方案。程式如下:

void combine(const char* str, const int nLen){unsigned int uCount = pow(2, nLen)-1;for (unsigned int i=1; i<=uCount; i++){unsigned int bitmap = i;// go through each bit of bitmapfor (unsigned int idx=0; idx < nLen; idx++){if (bitmap & 0x1)printf("%c", str[idx]);bitmap >>= 1;}printf("\n");}}

問題二 列印出從給定集合中選取指定個元素的所有組合。例如,從集合 {1, 2, 3, 4}中任取兩個元素的所有取法為{(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)}。

思路:借用多叉樹深度遍曆的方法。程式如下

#include <stdio.h>#include <stdlib.h>//          --- --- ---// pAssign | . | . | . |//          -*- -#- -$-////          -*- -#- --- -$- ---// list    | 2 | 6 | 7 | 9 | 8 //          --- --- --- --- ---// Idea: multiple tree traversal algorithm.//// Parameters://    list [in], defines the list of data.//    list_len [in], defines the length of the list.//    cmb [in], defines number of elements in the list to be combined.//void Combine(int* list, int list_len, int cmb){int** pAssign;// pointers that point to element in list.int curAssign = 0;int i;if (NULL == list || 0 == list_len || 0 == cmb){return;}pAssign = (int**)malloc(sizeof(int*) * cmb);pAssign[0] = list;curAssign = 1;while (1){// (Still need to assign)// and (amount need to assign <= amount available for assignment)while ((curAssign < cmb) &&(cmb-curAssign) <= (list_len - (pAssign[curAssign-1]-list) - 1)){pAssign[curAssign] = pAssign[curAssign-1] + 1;curAssign++;}// If all cmb have assigned then output.if (curAssign>=cmb){printf("(");for(i = 0; i < cmb; i++){printf("%d, ", *pAssign[i]);}printf("\b\b)\n");curAssign--;}// Find the position to walk right.while (pAssign[curAssign]-list >= list_len-1){curAssign--;}// If no cmb can walk right then return.if (-1 == curAssign){free(pAssign);return;}// walk right.pAssign[curAssign]++;curAssign++;}}

問題三。全排列。實現一個函數,列印給定集合元素的全排列。

例如,集合{1, 2, 3}的全排列如下:{(1, 2, 3), (1, 3, 2), (2, 1, 3), (2, 3, 1), (3, 1, 2), (3, 2, 1)}。

思路和問題二基本一致,是深度優先遍曆多叉樹的方法。

#include <stdio.h>#include <stdlib.h>int FindFirstAvailableIdxFrom(bool* list, int start, int list_len){int i;for(i = start+1; i < list_len; i++){if(false == list[i])return i;}return -1;}// Parameters://     list [in], defines the list of data.//     list_len [in], defines the length of the list.void Permutation(int* list, int list_len){int** pointers; // 指標數組,其中每個元素都指向list中的元素,表示輸出結果int** curLevel; // pointers中當前正在分配的元素bool* isOccupied;int i;int idx;pointers = (int**)malloc(sizeof(int*) * list_len);isOccupied = (bool*)malloc(sizeof(bool) * list_len);for(i=0; i<list_len; i++){pointers[i] = NULL;isOccupied[i] = false;}while(true){curLevel = pointers;while(list_len > curLevel - pointers){idx = FindFirstAvailableIdxFrom(isOccupied, 0, list_len);if(NULL != *curLevel){isOccupied[*curLevel - list] = false;}*curLevel = list + idx;isOccupied[idx] = true;curLevel++;}printf("{");for(i=0; i<list_len; i++){printf("%d, ", *(*(pointers+i)));}printf("\b}\n");while(-1 == (idx=FindFirstAvailableIdxFrom(isOccupied, *curLevel - list, list_len))){if (curLevel == pointers){return;}isOccupied[*curLevel - list] = false;curLevel--;}isOccupied[idx] = true;curLevel++;}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.