1、思路:
假设我们想在长度为n的字符串中求m个字符的组合。我们先从头扫描字符串的第一个字符。针对第一个字符,我们有两种选择:第一是把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选取m-1个字符;第二是不把这个字符放到组合中去,接下来我们需要在剩下的n-1个字符中选择m个字符。这两种选择都很容易用递归实现。
#include<iostream>
#include<vector>
#include<string.h>
using namespace std;
void combination(char* string,int number,vector<char>& result);
void combination(char* string)
{
if(string == NULL)
return;
vector<char> result;
int length = strlen(string);
for(int i = 1 ; i <= length; i++)
{
combination(string,i,result);
}
}
void combination(char* string,int number,vector<char>& result)
{
if(string == NULL)
return;
if(number == 0)
{
//static int index = 1;
//cout<<"第"<<index<<"个组合是:";
for(int i = 0; i < result.size();i++)
{
cout<<result[i];
}
cout<<" ";
return;
}
if(*string == '\0')
return;
result.push_back(*string);
combination(string+1,number-1,result);
result.pop_back();
combination(string+1,number,result);
}
int main()
{
char str[] = "aabc";
combination(str);
return 0;
}
思路二:位运算求组合,用一个二进制数字,来决定字符的取舍,某一位为1,则取对应的字符,若为0则不取,就能够实现字符组合。
N个字符的组合共有2n-1种组合方式,设置一个变量i从1增长到2n-1,i的二进制表示每个byte位上为1,则输出字符串中对应的字符。
例如字符串为”123”,当i为1的时候二进制为001,最低位为1,则对应的组合是3,i为7的时候二进制位111,则对应的组合为123.*/
要求输入的字符没有重复,否则输出组合结果中有重复的
#include<iostream>
#include<vector>
#include<string>
using namespace std;
vector<string> p(string str)
{
vector<string> ret;
if(str.size() == 0)
{
return ret;
}
int n = str.size();
int max = 1 << n;
for(int i = 1; i < max; i++)
{
int j = i;
string tmp = "";
int index = 0;
while(j)
{
if(j & 1)
{
tmp += str[index];
}
j>>= 1;
index++;
}
ret.push_back(tmp);
}
return ret;
}
int main()
{
string str = "aabc";
vector<string> ret = p(str);
for(int i = 0; i < ret.size(); i++)
{
cout<< ret[i] <<endl;
}
return 0;
}