概念就不用具体介绍了,这个不太容易忘记。
说下公式:
从n个不同元素中取出m个元素的排列数A(n,m) = n(n-1)(n-2)....(n-m+1) = n! / (n-m)!
从n个不同元素中取出m个元素的组合数C(n,m) = A(n,m) / m!= n!/ ((n-m)!* m!)
C(n,m) = C(n,n-m)
C(n,k) + C(n,k+1) = C(n+1, k+1)
C(n,0) + C(n,1) + C(n,2) + .... + C(n,n) = 2^n
求给定字符串的全排列和组合数(下面代码参考数据结构与算法(C++语言描述))
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
void swapAB(char *a, char *b)
{
char ch = *a;
*a = *b;
*b = ch;
}
//全排列
void perm(char str[], int k, int m)
{
if (k == m)
{
for (int i = 0; i <= m; i++)
printf("%c", str[i]);
printf("\t");
}
else
{
for (int i = k; i <= m; i++)
{
swapAB(&str[k], &str[i]);
perm(str, k+1, m);
swapAB(&str[k], &str[i]);
}
}
}
//组合数
void comb(char str[], int n, int m)
{
int *num = (int *)malloc(sizeof(int)*(n+1));
memset(num, 0, sizeof(int)*(n+1));
num[1] = 0;
int cnt = 1;
while (cnt != 0)
{
if (cnt != m)
{
num[cnt]++;
if (num[cnt] > n-m+cnt)
cnt--;
else
{
cnt++;
num[cnt] = num[cnt-1];
}
}
else
{
num[cnt]++;
for (int i = 1; i < m; i++)
printf("%c", str[num[i]-1]);
printf("%c ", str[num[m]-1]);
if (num[cnt] == n-m+cnt)
cnt--;
}
}
free(num);
num = NULL;
}
int main()
{
char str[] = "abcde";
int len = strlen(str);
//全排列
printf("字符串:%s\n\n全排列如下:\n", str);
perm(str, 0, len-1);
//组合数
printf("\n\n组合数如下:\n");
for (int i = 1; i <= len; i++)
{
comb(str, len, i);
printf("\n");
}
system("pause");
return 0;
}
运行结果如图: