手写算法! 每个小球都是独立唯一的。 盒子的数量是动态不固定的,每个盒子内的小球数量也是不固定的(至少1个)。从N个盒子里取球,每个盒子中每次取出一个,罗列出所有组合。

1 问题描述

每个小球都是独立唯一的。  盒子的数量N是动态不固定的,每个盒子内的小球数量也是不固定的(至少1个)。

从N个盒子里取球,每个盒子中每次取出一个,要设计一套算法,罗列出所有组合。

2 代码解决

个人这个问题用代码实现起来其实比较难,虽然题目只有简单的一行描述。

从遇到类似问题,到编码实现、自测通过,花了我整整有好几个小时!!!

真不知道是难,还是自己笨。

思路不写了,见代码!!  算法应该还有优化的空间,哥太累了,先这样!

#include 
#include 
#include 
using namespace std;


static int BOX_CNT = 1;

void printOneCompose(const vector& compose)
{
	for (size_t i = 0; i < compose.size(); i++)
	{
		printf("%d\t", compose[i]);
	}
	printf("\n");
}

//假设盒子是有序排列的,求第x(含)个盒子到第n(含)个盒子能组成的组合的最大数量
size_t a2bBoxComposeCnt(const vector& ball_cnts_in_boxes, size_t x, size_t n)
{
	if ( x > BOX_CNT || n > BOX_CNT || n < x)
	{
		return 0XFFFFFFFF;
	}

	if (ball_cnts_in_boxes.size() != BOX_CNT)
	{
		return 0XFFFFFFFF;
	}

	size_t all_compose_cnt = 1;
	for (size_t i = 1; i <= BOX_CNT; i++)
	{
		all_compose_cnt *= ball_cnts_in_boxes[i - 1];
	}

	if (all_compose_cnt < 1)
	{
		return 0XFFFFFFFF;
	}


	size_t cnt = 1;
	for (size_t i = x; i <= n; i++)
	{
		cnt *= ball_cnts_in_boxes[i - 1];
	}
	return cnt;
}

//模拟从N个箱子中取小球的过程,每个箱子每次都取出一个球,找出所有可能的组合,类似于递归几层for;
//balls_in_boxes.size=箱子数量;
//balls_in_boxes[i] 该箱子内的小球数量,必须大于等于1;
int composeFromBoxes(const vector& ball_cnts_in_boxes, 
					vector>& all_composes)
{
	if (ball_cnts_in_boxes.size() != BOX_CNT)
	{
		return -1;
	}

	size_t all_compose_cnt = 1;
	for (size_t i = 1; i <= BOX_CNT; i++)
	{
		all_compose_cnt *= ball_cnts_in_boxes[i-1];
	}

	if (all_compose_cnt < 1)
	{
		return -1;
	}

	all_composes.clear();

	vector one_compose;//一次从所有箱子里取小球的组合,箱子内小球索引从1开始算
	one_compose.resize(BOX_CNT);

	for (size_t iter = 1; iter <= all_compose_cnt; iter++)
	{
		std::fill(one_compose.begin(), one_compose.end(), 1);

		if (iter == 16)
		{
			int aaaaa = 0;
		}

		//1.首先确定当前iter在处于最后几个箱子范围里面,[start_boxes_idx, BOX_CNT]
		size_t start_boxes_idx = 0;
		size_t compose_cnt = 1;
		for (size_t b = BOX_CNT; b >= 1; b--)
		{
			compose_cnt *= ball_cnts_in_boxes[b - 1];
			if (iter <= compose_cnt)
			{
				start_boxes_idx = b;
				break;
			}
		}

		if (start_boxes_idx < 1)
		{
			return -1;
		}

		//2. 最后一个箱子就能应付iter
		if (start_boxes_idx == BOX_CNT)
		{
			one_compose[start_boxes_idx - 1] = iter;
			printOneCompose(one_compose);
			continue;
		}

		

		size_t cost_iter = 0;//已经消耗掉的iter
		//3. 需要2个及2个以上的箱子才能满足iter
		//确定箱子编号start_boxes_idx ~ BOX_CNT箱子编号的小球索引(从1开始算)
		for (size_t t = start_boxes_idx; t <= BOX_CNT ;t++)
		{
			if (t == start_boxes_idx)//首箱
			{
				//从第t+1个箱子倒第BOX_CNT个箱子的组合数
				size_t tmp_cnt = a2bBoxComposeCnt(ball_cnts_in_boxes, t + 1, BOX_CNT);
				if (0xFFFFFFFF == tmp_cnt)
				{
					return -1;
				}
				
				one_compose[t - 1] = iter / tmp_cnt ;
				if (one_compose[t - 1] == 0)
				{
					//one_compose[t - 1] = 1;
				}

				if (iter % tmp_cnt > 0)
				{
					one_compose[t - 1] += 1;
				}
			}
			else if(t == BOX_CNT)//尾箱
			{
				one_compose[t - 1] = iter % ball_cnts_in_boxes[t - 1];
				if (one_compose[t - 1] == 0)
				{
					one_compose[t - 1] = ball_cnts_in_boxes[t - 1];
				}
			}
			else//中间箱
			{
				cost_iter += (one_compose[t - 2] - 1) * a2bBoxComposeCnt(ball_cnts_in_boxes, t, BOX_CNT);
				size_t tmp_iter = iter - cost_iter;
				size_t tmp_cnt = a2bBoxComposeCnt(ball_cnts_in_boxes, t + 1, BOX_CNT);
				if (0xFFFFFFFF == tmp_cnt)
				{
					return -1;
				}
				one_compose[t - 1] = tmp_iter / tmp_cnt;
				if (one_compose[t - 1] == 0)
				{
					//one_compose[t - 1] = 1;
				}

				if (tmp_iter % tmp_cnt > 0 /*&& tmp_iter % tmp_cnt >= 1*/)
				{
					one_compose[t - 1] += 1;
				}

			}

		}//end for 倒序确定箱子编号BOX_CNT~箱子编号start_boxes_idx的小球索引

		printOneCompose(one_compose);

	}// end for 所有组合数量

	return 0;
}


int main()
{
	vector ball_cnts_in_boxes;
	vector> all_composes;

	//请注意 ball_cnts_in_boxes.size = BOX_CNT;
	ball_cnts_in_boxes.push_back(3);//设定每个盒子内有多少球!!!
	ball_cnts_in_boxes.push_back(3);
	ball_cnts_in_boxes.push_back(5);
	ball_cnts_in_boxes.push_back(1);
	BOX_CNT = 4;
	
	//返回0正常,其他值异常
	int res = composeFromBoxes(ball_cnts_in_boxes, all_composes);
	
	return 0;
}

3 结果

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

 

你可能感兴趣的:(数据结构与算法,算法)