题目
求字符串的所有组合,如字符串"ABC",它的组合有,A,B,C,AB,AC,BC,ABC。
思路
分治思想解决组合问题。如果输入n个字符,则这n个字符能构成长度为1的组合、长度为2的组合、…、长度为n的组合。在求n个字符的长度为m(1<=m<=n)的组合的时候,我们把这n个字符分成两部分:第一个字符和其余的所有字符。如果组合里包含第一个字符,则下一步在剩余的字符里选取m-1个字符;如果组合里不包含第一个字符,则下一步在剩余的n-1个字符里选取m个字符。也就是说,我们可以把求n个字符组合长度为m的组合的问题分解成两个子问题,分别求n-1个字符串中长度为m-1的组合,以及求n-1个字符的长度为m的组合。这两个子问题可以用递归的方式解决。
代码
#include <iostream>
#include <string>
using namespace std;
// StringCombination: 求一个字符集合中包含count个字符的组合情况有多少种
// count: 选取字符的数量
// total: 字符集合总的数量
// res: 输出结果
// characters: 字符集合
void StringCombination(int count, int total, string res, string characters)
{
// 检查输入合法性
if (total < 1 || count < 1 )
return;
// 从n个字符中选取1个字符
if (1 == count)
{
for (auto i : characters)
{
cout << res + i << endl;
}
return;
}
// 从n个字符中选取n个字符
if (total == count)
{
if (count != 1)
res += characters;
cout << res << endl;
}
// 从n个字符中选取m个字符,其中n>m
if (total > count)
{
// 弹出字符集合中的最后一个元素
char temp = characters.back();
characters.pop_back();
// 不选取第一个字符
StringCombination(count, total - 1, res, characters);
// 选取第一个字符
StringCombination(count - 1, total - 1, res + temp, characters);
}
}
void Combination(const string &str)
{
int len = str.length();
// 一个字符串的组合方式有多种,分别包含从1到n个的字符,n的大小等于字符串长度
for (int i = 1; i <= len; ++i)
{
StringCombination(i, len, string(""), str);
}
}
int main()
{
Combination("ABC");
return EXIT_SUCCESS;
}