c语言实现排列组合

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++;
    }
}

完整程序:

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

}

  

原文地址:https://www.cnblogs.com/gaoluyao/p/9441970.html

时间: 2024-10-10 23:52:43

c语言实现排列组合的相关文章

python 实现排列组合

1.python语言简单.方便,其内部可以快速实现排列组合算法,下面做简单介绍. 2.一个列表数据任意组合 2.1主要是利用自带的库 #_*_ coding:utf-8 _*_ #__author__='dragon' import itertools list1 = [1,2,3,4,5] list2 = [] for i in range(1,len(list1)+1): iter = itertools.combinations(list1,i) list2.append(list(ite

算法:C++排列组合

题目:给定1-n数字,排列组合. 解法:递归.第一个数字有n种选择,第二个数字有n-1种选择,依次递归排列输出.用数组表示n个数字,用过的数字置0. 实现语言:C++ #include <iostream> using namespace std; /************************************************************************/ /* num : 需要排列的数组 count : 数组总数 numC: 已经排列的数组 iUse:

自然语言处理(NLP) - 数学基础(1) - 排列组合

正如我在<自然语言处理(NLP) - 数学基础(1) - 总述>一文中所提到的NLP所关联的概率论(Probability Theory)知识点是如此的多, 饭只能一口一口地吃了, 我们先开始最为大家熟知和最基础的知识点吧, 排列组合. 虽然排列组合这个知识点大家是相当地熟知, 也是相当地基础, 但是却是十分十分十分地重要. NLP届掌门人斯坦福大学的Daniel Jurafsky(D. 朱夫斯凯)和科罗拉多大学James H. Martin(J. H. 马丁)在其NLP巨作<自然语言处

HDU--5396(区间dp+排列组合)

做这道题的时候,想到会不会是dp,然后发现dp可做,但是一直被自己坑到死. 枚举最后合并的那个位置,然后对于加减号的,分成的前后两个部分都有不同的组合方法, (a1+a2........) +  (b1,b2.............)         对于每个a,被加b的个数的阶乘次 ,对于每个b,被加a的个数的阶乘次 减法同理 乘法特殊一点 (a1+a2........) *  (b1,b2.............)  乘法分配率,直接将两部分的总和相乘即可 想到这些还远远没有结束,因为最

排列组合

(常考)错位排列 有N封信和N个信封,每封信都不装在自己信封里的排列种数记作Dn,则 D1=0,D2=1,D3=2,D4=9,D5=44,D6=265 一.相邻问题---捆绑法 不邻问题---插空法 对于某几个元素不相邻的排列问题,可先将其他元素排好,再将不相邻元素在已排好的元素之间及两端空隙中插入即可. [例题1]一张节目表上原有3个节目,如果保持这3个节目的相对顺序不变,再添进去2个新节目,有多少种安排方法? A.20 B.12 C.6 D.4 [答案]A. [解析] 以下内容需要回复才能看

hdu 1799 (循环多少次?)(排列组合公式)

循环多少次? Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3051    Accepted Submission(s): 1117 Problem Description 我们知道,在编程中,我们时常需要考虑到时间复杂度,特别是对于循环的部分.例如, 如果代码中出现 for(i=1;i<=n;i++) OP ; 那么做了n次OP运算

排列组合问题

一.不同元素子集问题 78. Subsets Given a set of distinct integers, nums, return all possible subsets. 给定一组非重复数字,求出所有可能的子集 解析: 例如 [1,2,3],解法: 首先放[],然后往已有的[]中放1 1. 首先放1 此时已有[ [], 1 ] 2. 然后对[ [], 1 ] 放2 于是此时有 [ [], [1], [2], [1,2] ] 3. 然后对[ [], [1], [2], [1,2] ]

排列组合问题之圆形分布

1.问题1.1 团团坐有一张圆桌,坐了A,B,C,D四个人,已知,D在A的右边,C在D的对面,请问A,B,C,D,的坐次? 解答:这个问题相对简单,我们纸上画一画,就能画出他们的可能的位置了 但是,可能还有一种解,比如我们把A,B,C,D依次右转一个位,也是满足条件的,而且只要保持他们的相对位置不变,依次右转n个位都是问题的解,而且还有个有趣的事情,当他们转了一圈(即右转4个位)后,他们右回到原位了 2.圆形分布上面这个问题就是一种圆形分布,那么他和直线分布的区别在哪里呢?又有什么联系呢?上面文

【noi 2.6_9288】&amp;【hdu 1133】Buy the Ticket(DP / 排列组合 Catalan+高精度)

题意:有m个人有一张50元的纸币,n个人有一张100元的纸币.他们要在一个原始存金为0元的售票处买一张50元的票,问一共有几种方案数. 解法:(学习了他人的推导后~) 1.Catalan数的应用7的变形.(推荐阅读:http://www.cnblogs.com/chenhuan001/p/5157133.html).P.S.不知我之前自己推出的公式“C(n,m)*C(2*m,m)/(m+1)*P(n,n)*P(m,m)”是否是正确的. (1)在不考虑m人和n人本身组内的排列时,总方案数为C(m+