字符串全排
准备工作:
- 1.递归版求全排字符串
map<string,int> m;//新建一个map用于筛选是否有重复序列
- 2.STL求全排字符串
调用algorithm库内自带的next_permutation函数即可
接口声明:
1.void permutation(string s,int begin=0)
算法核心:
- 1.如何理解全排列递归?
我们看全排列的性质,因为N的全排列公式等于N乘与N-1的全排列。所以我们让第一个字符的可能结果“乘与”N-1个字符串的全排列就是整体的全排列,依次递推下去,递推到当前位置后边没有字符串为止。
由于待求全排列的字符串里面可能有重复字符,按照这个算法输出的全排列结果中也会有重复结果,为了去重,新建一个map用于去重。
map<string,int> m;
void permutation(string s,int begin=0)//开始位置初始化为0
{
if(begin==s.size())//如果到了尽头,全部输出吧
{
if(m[s]==0)
++m[s];
return;
}
for(int j=begin;j<s.size();j++)//这个for循环用来生成当前字符串begin位置的可能结果
{
swap(s[j],s[begin]);
permutation(s,begin+1);
swap(s[j],s[begin]);
}
}
- 2.直接调用 next_permutation(开始地址,结束地址的下一个地址)即可,非常简单,而且结果自动消除重复序列
string s;
cin>>s;
do{
cout<<s<<endl;
}
while(next_permutation(s.begin(),s.end()));
字符串组合
准备工作:
新建一个字符栈,用于存储当前组合的一种情况
vector<char> v;
接口声明:
- 1.void combination(string s,int num,int begin=0)//开始位置初始化为0
算法核心:
- 如何理解字符串组合?
假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:第一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;第二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。那么可以说任何一个字符,都有这两种组合。
我们可以新建一个vector变量用于存储字符,新建一个int型的num表明当前还剩余多少字符未存储,新建一个int型的begin变量标记当前位点,num为0时输出vector变量中的字符串并返回到上一层,begin到终点时也返回到上一层。
void combination(string s,int num,int begin=0)
{
if(num==0)//递归完毕
{
vector<char>::iterator it;
for(it=v.begin();it!=v.end();it++)
cout<<*it;
cout<<endl;
return;
}
if(begin==s.size())
return;
//组合的两种可能
v.push_back(s[begin]);
combination(s,num-1,begin+1);
v.pop_back();
combination(s,num,begin+1);
}
#pragma warning (disable:4786)
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
//字符串全排
void permutation(string s,int begin);
map<string,int> m;
//字符串组合
vector<char> v;
void combination(string s,int num,int begin);
//字符串全排
void permutation(string s,int begin=0)
{
if(begin==s.size())
{
if(m[s]==0)
++m[s];
}
for(int j=begin;j<s.size();j++)
{
swap(s[j],s[begin]);
permutation(s,begin+1);
swap(s[j],s[begin]);
}
}
//字符串组合
void combination(string s,int num,int begin=0)
{
if(num==0)
{
vector<char>::iterator it;
for(it=v.begin();it!=v.end();it++)
cout<<*it;
cout<<endl;
return;
}
if(begin==s.size())
return;
v.push_back(s[begin]);
combination(s,num-1,begin+1);
v.pop_back();
combination(s,num,begin+1);
}
int main()
{
string s;
cin>>s;
// 字符串全排
// permutation(s);
// map<string,int>::iterator it;
// for(it=m.begin();it!=m.end();it++)
// cout<<it->first<<endl;
// 字符串组合
// for(int i=1;i<=s.size();i++)
// combination(s,i);
// return 0;
}