排列组合问题,在学到深度优先搜索时候,经常遇到,这篇文章重点讲组合问题。ps:因为排列问题比组合问题简单很多。
首先我们必须了解排列和组合的区别,其实只有一点:排列讲究顺序,而组合不需要,所以这就是刚才排列较为简单的原因,直接深度搜索,不用考虑啥因素。但是组合问题,如果不在深度搜索里做点啥,会导致1 2 5, 1 5 2这样重复的一组出现。
我们来说说我实现组合的原理:其实无论你给定什么类型的数据,都可以看成是字符数组,对吧。无论你给定的是什么样的字符数组,我都可以看成是1 2 3 4 5 6…这样的数字组合,因为这些数字我可以看成是字符数组的下标,然后我把下标对应的字符拿出来,就是一个组合了,小编我还是可以的吧,哈哈。
比如:abxy这个数组,想要解决不重复问题,其实只要解决深度搜索每次不要重新回头搜索的问题。我的办法:初始化一个整数 bj 数组,初值为0
dfs(x=1)的时候,i=bj[x-1]+1 开始,这句话很起作用,它能保证你的 i 不会每次重新开始,只要在上一个搜索下标的后面开始搜索。
下面小编给出字符组合代码,其实我觉得字符组合就可以解决一切了。
#include <cstdio>
#include <iostream>
#include <iomanip>
using namespace std;
int n, r;
char a[22];
int aa[22]={0};
bool b[22] = {0};
string res;
int search(int);
int print();
int main()
{
cin >> n >> r;
for(int i=1;i<=n;i++){
cin>>a[i];
}
search(1);
}
int search(int k)
{
int i;
if(k==r+1)print();
for (i = aa[k-1]+1; i <=n; i++) //按由小到大的顺序排列,所以从上一个添加的数+1 开始搜索数字
{
if (!b[i])
{
aa[k]=i;
res+=a[aa[k]];
b[i] = 1;
search(k + 1);
b[i] = 0;
res.erase(res.size()-1);
}
}
}
int print()
{
cout<<res;
cout << endl;
}
如果觉得文章帮助到你的话,给小编一个赞喔。。