排列與組合是數學裡的經典問題,由這個問題可引申出子集、字典排序等問題,那麼,我們先看經典的排列與組合,怎麼在程式裡實現。
在網上搜了一下,關注這個問題的人還是挺多的,有不了人給出的回答是使用幾個for
迴圈進行巢狀,例如取
3個數的排列則使用3個
for迴圈
i,j,k
巢狀,當
i,j,k
互不相等時進行輸出,這樣的函式雖然是正確的,但是沒有通用性,我們要實現的是從m中取
n,m、
n皆為變數。
通過數學公式我們知道,
先來看排列的實現,假如集合為{abc
},取出
2個的排列為
ab ac ba bc ca cb
,從這裡我們不難看出,第乙個字母可從{
abc}中任取乙個,假如選了
a,第二字母從剩下的集合中{
bc}再任選乙個,這樣便完成了排列,規則其實很簡單,取
n個數,從第乙個數開始選,選完之後從集合中去掉這個數,開始選第
2個數,一直到取第
n個數為止。
程式裡我們這樣設計,對乙個陣列裡的元素進行排列,我們可將陣列分為兩部分,已排集合及未排的集合,每次挑選第i
個數時,
arr[0]
至arr[i-1]
為已排集合,未排集合為
arr[i]
至arr[m-1]
,這裡從未排集合中依次取出乙個元素,交到當前
arr[i]
的位置,此時未排集合變為
arr[i+1]
至arr[m-1]
,並開始遞迴選擇
i+1個數,直到
i=n,選擇結束,請看下圖:
下面來看組合數的情況,設集合為,選則3
個數進行組合,組合情況為
:abc
abdacd
bcd情況與排列的類似,但有一點不同的是,假設第乙個數選了a
,則剩下的集合為{
bcd},這樣便輸出了所有包含
a的組合情況;這時,當第乙個數選了
b時,則剩下的集合為
,而不是
,因為所有包含
a的組合已經輸出了,即
a已經從當前集合中排除了。
程式裡我們這樣設計,對乙個陣列裡的元素進行排列,我們可將陣列分為兩部分,已選擇的集合及未排的集合,每次挑選第i
個數時,
arr[0]
至arr[i-1]
為已排元素,未排集合為
arr[j]
至arr[m-1]
,這裡未排集合中依次取出乙個元素,假設為
arr[k]
,其中k
在[j,m-1]
之間,交換到當前
arr[i]
的位置,此時未排集合為
arr[k+1]
至arr[m-1]
,並開始遞迴選擇
i+1個數,直到
i=n,選擇結束。
【檢視完整**實現】
C語言實現排列組合
include include int array define n 4 define m 3 int results n 儲存已經找到的結果字首陣列 int results end 0 結果字首陣列有效資料下標 int is used n 是否已經排列過了的標誌 排列 param deep 遞迴深...
c語言實現排列組合
1.求排列組合結果總數 組合 採用遞迴演算法,根據下面第二行公式。k 排列 採用遞迴。思想來自 int sumpailie int n,int k 2.展示排列,組合結果。排列 首先從 n 個中取乙個數,再在剩餘的一次次取乙個數,每取乙個數就把這位標記為取過了,以免下次再取。取夠k個數之後,把k個數...
C語言實現排列組合(全排列)
題目描述 排列與組合是常用的數學方法。先給乙個正整數 1 n 10 例如n 3,所有組合,並且按字典序輸出 1 2 3 1 3 2 2 1 3 2 3 1 3 1 2 3 2 1 輸入 輸入乙個整數n 1 n 10 輸出 輸出所有全排列 每個全排列一行,相鄰兩個數用空格隔開 最後乙個數後面沒有空格 ...