这是数据结构老师布置的第三道作业题,题目具体要求如下:
具体实现思路如下:
假如说我们要找出在{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,这里容易出错,可以在演草纸上演算一下。