定义一个数组,编程打印它的全排列。比如定义:
#define N 3
int a[N] = { 1, 2, 3 };
运行结果是:
$ ./a.out
1 2 3
1 3 2
2 1 3
2 3 1
3 2 1
3 1 2
1 2 3
程序的主要思路是:
- 把第1个数换到最前面来(本来就在最前面),准备打印1xx,再对后两个数2和3做全排列。
- 把第2个数换到最前面来,准备打印2xx,再对后两个数1和3做全排列。
- 把第3个数换到最前面来,准备打印3xx,再对后两个数1和2做全排列。
可见这是一个递归的过程,把对整个序列做全排列的问题归结为对它的子序列做全排列的问题。程序需要具有通用性,如果改变了N和数组a的定义(比如改成4个数的数组),其它代码不需要修改就可以做4个数的全排列(共24种排列)。
完成了上述要求之后再考虑第二个问题:如果再定义一个常量M表示从N个数中取几个数做排列(N == M时表示全排列),原来的程序应该怎么改?
最后再考虑第三个问题:如果要求从N个数中取M个数做组合而不是做排列,就不能用原来的递归过程了,想想组合的递归过程应该怎么描述,编程实现它。
- 排列的递归代码实现
#include <stdio.h>
#include <stdlib.h>
#define N 100
int a[N], c[N], s;
void fun(int m, int n, int a[N])
{
int i, j, k = 0, b[N];
if (m == s) {
for (i = 0; i < m - 1; i++)
printf("%d ", c[i]);
printf("%d\n", c[m - 1]);
return;
} else {
for (i = 0; i < n; i++) {
c[m] = a[i];
k = 0;
for (j = 0; j < n; j++) {
if (j != i) {
b[k] = a[j];
k++;
}
}
fun(m + 1, n - 1, &b[0]);
}
}
}
int main(void)
{
int i, n;
printf("Please input array size:");
scanf("%d", &n);
printf("Please input array element:");
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("Please input select permutation count:");
scanf("%d", &s);
printf("all permutation result:\n");
fun(0, n, &a[0]);
return 0;
}
对于数组a[n],从中选s个元素的排列并打印出来
运行结果:
hero@debian:~$ gcc -Wall permutation.c -o permutation
hero@debian:~$ ./permutation
Please input array size:3
Please input array element:1 2 3
Please input select permutation count:3
all permutation result:
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
hero@debian:~$ ./permutation
Please input array size:3
Please input array element:1 2 3
Please input select permutation count:2
all permutation result:
1 2
1 3
2 1
2 3
3 1
3 2
- 组合的递归代码实现
#include <stdio.h>
#include <stdlib.h>
#define N 100
int a[N], c[N], s, n;
void fun(int m, int x, int t, int a[N])
{
int i;
if (m == s) {
for (i = 0; i < m - 1; i++)
printf("%d ", c[i]);
printf("%d\n", c[m - 1]);
return;
} else {
for (i = x; i < n - t + 1; i++) {
c[m] = a[i];
if (t == 1)
fun(m + 1, i + 1, t, &a[0]);
else
fun(m + 1, i + 1, t - 1, &a[0]);
}
}
}
int main(void)
{
int i;
printf("Please input array size:");
scanf("%d", &n);
printf("Please input array element:");
for (i = 0; i < n; i++)
scanf("%d", &a[i]);
printf("Please input select combination count:");
scanf("%d", &s);
printf("all combination result:\n");
fun(0, 0, s, &a[0]);
return 0;
}
对于数组a[n],从中选s个元素的组合并打印出来
运行结果:
hero@debian:~$ gcc -Wall combination.c -o combination
hero@debian:~$ ./combination
Please input array size:3
Please input array element:1 2 3
Please input select combination count:3
all combination result:
1 2 3
hero@debian:~$ ./combination
Please input array size:3
Please input array element:1 2 3
Please input select combination count:2
all combination result:
1 2
1 3
2 3