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");

     

}

发布了134 篇原创文章 · 获赞 116 · 访问量 65万+

猜你喜欢

转载自blog.csdn.net/shixin_0125/article/details/103926470
今日推荐