简单枚举---从一数组中任取n个元素

原创 2013年12月02日 14:25:19
在解决POJ753-Flip Games之前,我们先来看这样一个问题:"给出一个数组a[6]={1,2,3,4,5,6},求从中任取n个元素的所有组合。"


如果任取1个元素,那么组合是:

1  ,2  ,3  ,4  ,5 ,6.

如果任取2个元素,那么组合是:

1 2,1 3,1 4,1 5,1 6.

2 3,2 4,2 5,2 6.

3 4,3 5,3 6.

4 5,4 6.
5 6.

不再举例。


这个问题很明显的需要用枚举的思想来一一遍历数组元素并进行无重复组合,但是算法该怎么实现呢?


如果任取3个元素,首先我得先找第一个元素,考虑到不重不漏:


第一个元素只能从1~4中选取;
假如第一个元素取1,第二个元素就只能从2~5中选取;
如果第一个元素选1第二个元素选2,第三个元素就只能从3~6中选取。
以此类推。

所以这时我们就可以考虑到用递归的思想来解决枚举的算法:

首先枚举选取第一个元素,并把其存储在一个数组中,在第一个元素枚举完后,如果规定的元素选取个数没有达到,则从已取得的第一个元素之后开始,再进行枚举,直到完成规定元素选取个数。在枚举选取的同时把选出来的元素按序依次存储在一个数组里面,完成选取后把数组中的元素全部输出即可。

算法实现如下

void ienum(int start, int count, int NUM, int a_len, int *a, int *tem) 
{/*start为枚举初始位置,count为选取个数计数器,NUM为选取个数,a_len为给出的数组长度,*a为给出的数组,*tem为暂时存放选取出的元素的数组*/
	int i, j;
	for(i = start; i<=a_len-count; ++i)/*元素枚举范围*/
	{
		tem[count-1] = a[i];/*把选出来的元素按序依次存储在数组tem[]里面*/
		if(0 == count-1) /*判断是否完成所需选取个数*/
		{
			for(j = NUM-1; j>=0; --j)
				printf("%d ",tem[j]);
			printf("\n");
		}
		else /*否则缩小枚举范围,进行下一个元素的枚举选取*/
			ienum(i+1, count-1, NUM, a_len, a, tem);
	}
}

完整代码如下:
#include <stdio.h>
void ienum(int start, int count, int NUM, int a_len, int *a, int *tem) 
{
	int i, j;
	for(i = start; i<=a_len-count; ++i)
	{
		tem[count-1] = a[i];
		if(0 == count-1)
		{
			for(j = NUM-1; j>=0; --j)
				printf("%d ",tem[j]);
			printf("\n");
		}
		else
			ienum(i+1, count-1, NUM, a_len, a, tem);
	}
}

int main()
{
	int num, tem[6], a[6] = {1,2,3,4,5,6};
	for(num = 1; num<=6; ++num)/*从中任取1个~6个元素的所有组合*/
		ienum(0, num, num, 6, a, tem);

	getchar();
	return 0;
}

结果输出:






1 2 
1 3 
1 4 
1 5 
1 6 
2 3 
2 4 
2 5 
2 6 
3 4 
3 5 
3 6 
4 5 
4 6 
5 6 
1 2 3 
1 2 4 
1 2 5 
1 2 6 
1 3 4 
1 3 5 
1 3 6 
1 4 5 
1 4 6 
1 5 6 
2 3 4 
2 3 5 
2 3 6 
2 4 5 
2 4 6 
2 5 6 
3 4 5 
3 4 6 
3 5 6 
4 5 6 
1 2 3 4 
1 2 3 5 
1 2 3 6 
1 2 4 5 
1 2 4 6 
1 2 5 6 
1 3 4 5 
1 3 4 6 
1 3 5 6 
1 4 5 6 
2 3 4 5 
2 3 4 6 
2 3 5 6 
2 4 5 6 
3 4 5 6 
1 2 3 4 5 
1 2 3 4 6 
1 2 3 5 6 
1 2 4 5 6 
1 3 4 5 6 
2 3 4 5 6 
1 2 3 4 5 6


单元素枚举类实现单例模式

本文转载自:点击打开链接 Inspired by Effective Java. Singleton模式是在编程实践中应用最广泛的几种设计模式之一。以前知道的,实现单例的方法有两种(下...
  • see__you__again
  • see__you__again
  • 2016年06月03日 15:15
  • 1588

java枚举元素集合

Set是Java集合类的重要组成部分,它用来存储不能重复的对象。枚举类型也要求其枚举元素各不相同。看起来枚举类型和集合是很相似的。然而枚举类型中的元素不能随意的增加、删除,作为集合而言,枚举类型非常不...
  • sunhuwh
  • sunhuwh
  • 2014年09月25日 23:51
  • 1553

浅谈使用单元素的枚举类型实现单例模式

简介 使用单元素的枚举实现单例模式简介通常情况下,我们写单例模式的时候无非就是三个步骤:构造器私有化,声明私有静态变量,提供静态获取实例的方法。简单说就是以下这种方式:class SingletonA...
  • huangyuan_xuan
  • huangyuan_xuan
  • 2016年08月12日 22:47
  • 5554

QMetaEnum获取枚举元信息

QMetaEnum 类提供了一个枚举的元数据。我们可以使用该类的静态模板函数,fromType来获得关于某个枚举的QMetaEnum对象,然后就可以调用该类的成员函数来获得该枚举的相关信息。该枚举必须...
  • Amnes1a
  • Amnes1a
  • 2017年04月04日 17:02
  • 1073

利用枚举类型变量求从5种颜色球中取3个不同颜色球的取法

利用枚举类型变量求从5种颜色球中取3个不同颜色球的取法 《Ccxu》
  • lyc_daniel
  • lyc_daniel
  • 2014年04月10日 09:23
  • 2977

C语言enum枚举类型解析(转)

在实际应用中,有的变量只有几种可能取值。如人的性别只有两种可能取值,星期只有七种可能取值。在 C 语言中对这样取值比较特殊的变量可以定义为枚举类型。所谓枚举是指将变量的值一一列举出来,变量只限于列举出...
  • diyinqian
  • diyinqian
  • 2017年07月06日 14:24
  • 336

OC中的两种枚举解释

下面来简单的解释一下OC里枚举的两种类型. NS_ENUM和NS_OPTIONS 本质上是一样的都是枚举. 我举个例子. typedef NS_ENUM(NSInteger, UIViewAnima...
  • CharlesYaoxin
  • CharlesYaoxin
  • 2015年10月18日 19:52
  • 1387

java枚举类型enum值与整数的转换

java编程中偶尔会用到枚举,为了直观,我们通常将枚举值设置为形象的单词,方便理解和使用。枚举类型相当于数据库 中字典表,但是枚举只有字典表的值,缺少其他用来表示和值一一对应的字段,当我们在数据库中...
  • feinifi
  • feinifi
  • 2017年03月16日 14:29
  • 2550

JavaScript中的可枚举属性与不可枚举属性

在JavaScript中,对象的属性分为可枚举和不可枚举之分,它们是由属性的enumerable值决定的。可枚举性决定了这个属性能否被for…in查找遍历到。 一、怎么判断属性是否可枚举 ...
  • mrhaoxiaojun
  • mrhaoxiaojun
  • 2017年04月27日 11:40
  • 398

获取Enum枚举值描述的几法方法

1.定义枚举时直接用中文 由于VS对中文支持的很不错,所以很多程序员都采用了此方案. 缺点:1.不适合多语言 2.感觉不太完美,毕竟大部分程序员大部分代码都使用英文 2.利用自定义属性定义枚举值...
  • LIAO_Love
  • LIAO_Love
  • 2017年07月12日 14:40
  • 1016
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:简单枚举---从一数组中任取n个元素
举报原因:
原因补充:

(最多只允许输入30个字)