[遞迴] 排列組合 - 從一個字串中任意選取N個元素構成的所有排列組合 - C語言
阿新 • • 發佈:2018-11-12
排列組合
【題目】求從字串中"ABCD"中任取3個元素構成的所有排列組合
- 先從ABCD中選3個元素,然後對這三個元素進行全排列
【如何求排列】https://blog.csdn.net/summer_dew/article/details/83097993
【如何求組合】https://blog.csdn.net/summer_dew/article/details/83315100
【結果】
【程式碼】
#include<stdio.h>
int combination_permutation(char tmp[], int n);
int combination(char *tmp,int m, int index);
int permutation(char str[],int sbegin, int send);
void swap(char *c1, char *c2);
int main() {
char tmp[50];
int n;
int cnt;
scanf("%s", tmp);
scanf("%d", &n);
// tmp中選n個進行全排列
cnt = combination_permutation(tmp, n);
printf("\n種數:%d\n", cnt);
return 0;
}
int combination_permutation(char tmp[], int n) {
return combination(tmp, n, 0);
}
char arr[50];
// 在tmp陣列中選m個,第m個放在index的位置
int combination(char *tmp,int m, int index) {
int case1, case2;
if (m==0) { //選完了
// 把arr進行全排列
arr[index] = '\0';
//printf("%s\n", arr);
return permutation(arr, 0, index-1);
}
if (*tmp!='\0') {
//選*tmp
arr[index] = *tmp;
case1 = combination(tmp+1, m-1, index+1);
//不選*tmp
case2 = combination(tmp+1, m, index);
return case1 + case2;
}
return 0;
}
// 將str中[sbegin, send]中進行全排列
int permutation(char str[], int sbegin, int send) {
int i;
int cnt=0;
if(sbegin == send) {//當 sbegin = send時輸出
for( i = 0; i<=send; i++) //輸出一個排列
printf("%c", str[i]);
printf("\n");
return 1;
}
else {
for( i = sbegin; i <= send; i++) {//迴圈實現交換和sbegin + 1之後的全排列
swap(&str[i], &str[sbegin]); //把第i個和第sbegin進行交換
cnt += permutation(str, sbegin + 1, send);
swap(&str[i], &str[sbegin]); //【注1】交換回來
}
}
return cnt;
}
void swap(char *c1, char *c2) {
char tmp;
tmp = *c1;
*c1 = *c2;
*c2 = tmp;
}
【如果只選3個,可以用以下暴力的方法】
/*
* @Test:口袋中有紅、黃、藍、白、黑5種顏色的球若干個。每次從口袋中先後取3個球,問取到3種不同顏色的球的可能取法,輸出每種排列的情況
*/
#include<stdio.h>
int main() {
enum Color {red,yellow,blue,white,black};
enum Color i,j,k,pri;
int n,loop;
n=0;
for (i=red; i<=black; i++) {
for (j=red; j<=black; j++) {
if (i!=j) {
for (k=red; k<=black; k++) {
if ( (i!=k) && (j!=k) ) {
n++;
printf("%-4d",n);
for(loop=1; loop<=3; loop++) {
switch (loop) {
case 1:pri=i;break;
case 2:pri=j;break;
case 3:pri=k;break;
default:break;
}
switch(pri) {
case red : printf("%-10s","red"); break;
case yellow : printf("%-10s","yellow"); break;
case blue : printf("%-10s","blue"); break;
case white : printf("%-10s","white"); break;
case black : printf("%-10s","black"); break;
default:break;
}
}
printf("\n");
}
}
}
}
}
printf("\ntotal:%5d\n",n);
return 0;
}