找出n个符号中所有m个符号的组和

这是数据结构老师布置的第三道作业题,题目具体要求如下:

具体实现思路如下:

  假如说我们要找出在{1,2,3,4}中所有的两个符号的组合,那么我们可以先把1选中,然后看2。这里出现了分支,如果我们将2也选中,那么就结束;如果说我们不选中2,而是在剩下的2个元素中选出最后一个元素...如此看来,这是一个可以用递归解决的问题,递归的思路如下:

  当我们碰到了某个数,我们可以选中它,然后在未碰到过的元素中继续寻找剩下的元素。或者我们也可以不选中它,然后在剩下的元素中继续寻找其他的元素。

代码实现如下(c++)

#include"pch.h"
#include<iostream>
#include<vector>
using namespace std;

void find(vector<int> input, int current, int m, vector<int> result)
/*input是要处理的数组,current代表当前处理到的下标,
m代表还要找寻的元素的个数,result用于存放找寻的结果
*/
{
	if (m == 0)//首先判断要找寻的元素个数是否为0,如果为零,代表到达了递归边界
	{
		//输出第index个组合
		static int index = 1;
		vector<int>::iterator iter = result.begin();
		cout << "第" << index++ << "个组合是:";
		for (; iter < result.end(); iter++)
		{
			cout << *iter;
		} 
		cout << endl;
		return;
	}
	if (current == input.size())//如果当前的current和数组元素总数相等,返回
		return;
	result.push_back(input[current]);//假如我选择了该元素
	find(input, current + 1, m - 1, result);//我只需要在剩下的元素中寻找m-1个元素即可
	result.pop_back();//假如我没有选择该元素
	find(input, current + 1, m, result);//我需要在剩下的元素中寻找m个元素
}
void checkIfValid(vector<int> input, int m)//用来检测该请求是否合法
{
	if (input.size() == 0)//如果数组为空,那么返回
		return;
	if (m > input.size())//如果说抽取的m大于数组的元素总数,非法,返回
		return;
	vector<int> result;//用于存放抽取结果
	find(input, 0, m, result);//正常运行
}

int main()
{
	/*输入需要处理的参数,n代表数组中总共有多少元素,m代表单个组合要抽取多少元素,
	比如说按题目中的要求,m=2,n=4*/
	int n, m;
	cout << "Enter the quantity: ";
	cin >> n;
	cout << "Enter the selected quantity: ";
	cin >> m;
	//输入要处理的数组
	vector<int> input;
	for (int i = 0; i < n; i++)
	{
		int temp;
		cin >> temp;
		input.push_back(temp);
	}
	//展示结果
	cout << "The result is as follows: \n";
	checkIfValid(input, m);
}

运行结果如下:

值得一提的是,如果说先判断current是否等于数组元素总数的话,每个组合都会少一种可能性,所以应该先判断当前要找寻的元素个数m是否为0,这里容易出错,可以在演草纸上演算一下。

猜你喜欢

转载自blog.csdn.net/weixin_41106545/article/details/83028936