现在的位置: 首页 > 综合 > 正文

编程挑战(6)

2019年01月11日 ⁄ 综合 ⁄ 共 1451字 ⁄ 字号 评论关闭

组合算法:开一个数组,其下标表示1到m个数,数组元素的值为1表示其下标代表的数被选中,为0则没有选中。

 首先初始化,将数组前n个元素置1,表示第一个组合为前n个数;然后从左到右扫描数组元素值的“10”组合,找到第一个“10”组合后将其变为“01”组合,同时将其左边的所有“1”全部移动到数组的最左端;当第一个“1”移动到数组的m-n位置,即n个“1”全部移动到最右端时,就得到了最后一个组合。

       例如求5中选3的组合:

       1     1     1     0     0     //1, 2, 3

       1     1     0     1     0     //1, 2, 4

       1     0     1     1     0     //1, 3, 4

       0     1     1     1     0     //2, 3, 4

       1     1     0     0     1     //1, 2, 5

       1     0     1     0     1     //1, 3, 5

       0     1     1     0     1     //2, 3, 5

       1     0     0     1     1     //1, 4, 5

       0     1     0     1     1     //2, 4, 5

       0     0     1     1     1     //3, 4, 5

void output1(int value[], char* middle, int length)
{
	for(int i=0; i<length; i++)
	{
		if(middle[i] == '1')
		{
			printf("%d ", value[i]);
		}
	}
	printf("\n");
}

bool find10(char* middle, int M, int* index)
{
	bool find = false;
	for(int i=0; i<M; i++)
	{	
		if (middle[i] == '1' && middle[i + 1] == '0')
		{
			*index = i;
			find = true;
			break;
		}
	}
	return find;
}

void move1(char* middle, int index)
{
	int count = 0;
	for(int i=0; i<index; i++)
	{
		if (middle[i] == '1')
		{
			swap(middle[count++], middle[i]);
		}
	}
}

//从M 个数中取 N 个数的组合
void enumkind(int value[], int M, int N)
{
	char *middle = new char[M + 1];
	middle[M] = '\0';
	memset(middle, '1', N);
	memset(middle + N, '0', M - N);
	
	printf("%s: ", middle);
	output1(value, middle, M);

	int index = 0;
	while(find10(middle, M, &index))
	{
		swap(middle[index], middle[index+1]);
		move1(middle, index);
		printf("%s: ", middle);
		output1(value, middle, M);
	}

	delete middle;
}




int _tmain(int argc, _TCHAR* argv[])
{
	int value[5] = {1,2,3,4,5};

	enumkind(value, sizeof(value)/sizeof(int), 4);

	getchar();
	return 0;
}

 

【上篇】
【下篇】

抱歉!评论已关闭.