c语言实现排列组合:实现matlab中的nchoosek函数
1.求排列組合結果總數
? ? 組合:采用遞歸算法,根據下面第二行公式。
? ? ?
int sumzuhe(int N, int K) {if (K == 0)return 1;if (N == K)return 1;return sumzuhe(N - 1, K - 1) + sumzuhe(N - 1, K); }? ? 排列:采用遞歸。思想來自:https://blog.csdn.net/u012814856/article/details/73863086。
int sumpailie(int N,int K) {if (K ==1)return N;return sumpailie(N - 1, K - 1)*N;}2.展示排列,組合結果。
? ? 排列:首先從(N)個中取一個數,再在剩余的一次次取一個數,每取一個數就把這位標記為取過了,以免下次再取。取夠K個數之后,把K個數輸出,展示結果(所以需要提前有一個數組來存 ? ? ? ? ? ? ? ? 放結果)。然后再取尋找別的第K個數,依次在不斷尋找別的第(K-1),(K-2),,,,,個數。取完一個數把標記位設為未取過。
void pailie(int a[],int N,int K,int level)//(K==N)時為全排列 {if (level>=K){ for (int j = 0; j < level; j++)printf("%d ", result[j]);printf("\n");return;}for (int i = 0; i < N; i++){if (flag[i] == false)//該位未取過{flag[i] = true;result[level++] = a[i];//取出修改標記位pailie(a, N, K , level);//在未被使用過的里面再選擇一個level--;//重新取別的位flag[i] = false;}} }?
? ? ? ?組合:組合與排列不同的是:不分順序。我們可以假設一直是從前往后選數,那么前面作為開頭的數,后面就不可以再作為開頭。比如:A,B,C,D。當我第一次選擇第一個數為A的話,把以A為頭的數選完之后,下一次選第一個數決不能是A。所以需要有一個變量來控制所選擇的第一個數(下面的程序為Index)。然后再在第一個數(比如選擇A)之后的數中挑選接下來的數。選擇接下來的數與上面排列類似。
void zuhe(int a[], int N, int K,int index,int deep) {if (deep >= K){for (int i = 0; i < K; i++){printf("%d ", result[i]);}printf("\n");return;}for (int i = index; i <N; i++){result[deep] = a[i];deep++;zuhe(a, N, K, index + 1, deep);deep--;index++;} }完整程序:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 | #include "stdio.h" #define Max? 10 #define length 10 typedef enum bool{ true,false}bool; char flag[10] ; int? result[10]; int sumzuhe(int N, int K) { ????if (K == 0) ????????return 1; ????if (N == K) ????????return 1; ????return sumzuhe(N - 1, K - 1) + sumzuhe(N - 1, K); } void? pailie(int a[],int N,int K,int level) { ?????if (level>=K) ????????{ ????????for (int j = 0; j < level; j++) ????????????printf("%d ", result[j]); ????????printf("\n"); ????????return; ????} ????for (int i = 0; i < N; i++) ????{ ????????if (flag[i] == false) ????????{ ????????????flag[i] = true; ????????????result[level++] = a[i]; ????????????pailie(a, N, K , level);//在未被使用過的里面再選擇一個 ????????????level--; ????????????flag[i] = false; ????????} ????} } void? zuhe(int a[], int N, int K,int index,int deep) { ????if (deep >= K) ????{ ????????for (int i = 0; i < K; i++) ????????{ ????????????printf("%d ", result[i]); ????????} ????????printf("\n"); ????????return; ????} ????for (int i = index; i <N; i++) ????{ ????????result[deep] = a[i]; ????????deep++; ????????zuhe(a, N, K, index + 1, deep); ????????deep--; ????????index++; ? ????} } ? int sumpailie(int N,int K) { ????if (K ==1) ????????return N; ????return sumpailie(N - 1, K - 1)*N; ? } void main() { ????int a[5] = { 1,2,3,4,5}; ????memset(flag, false, sizeof(flag)); ????printf("排列結果數(5,3):\n"); ????printf("%d ", sumpailie(5, 3)); ????printf("\n"); ????printf("排列結果(5,3):\n"); ????pailie(a, 5, 3, 0); ????printf("全排列結果:\n"); ????pailie(a, 5, 5, 0); ? ????printf("組合結果數(5,3):\n"); ????printf("%d ", sumzuhe(5, 3)); ????printf("\n"); ????printf("組合結果(5,3):\n"); ????zuhe(a, 5, 3, 0, 0); ????printf("\n"); ????? } |
總結
以上是生活随笔為你收集整理的c语言实现排列组合:实现matlab中的nchoosek函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: std::map 反向遍历
- 下一篇: MATLAB排列组合函数--nchoos