题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
分析:递归实现,根据组合公式C(n,k) = C(n-1,k) + C(n-1,k-1), 如果我们想要在长度为n的字符串中求k个字符的组合,首先选择第一个字符,对余下n-1个字符可以分为两个部分进行求解:
(1)当前组合中包含当前字符,那么只需要在剩下的n-1个字符中选择k-1个字符,组成k个字符的组合。
(2)当前组合中不包含当前字符,那么就需要在剩下的n-1个字符中选择k个字符,组成k个字符的组合。
递归源码:
/*
输入一个字符串,输出该字符串中字符的所有组合。
举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。
*/
void Combination(char* str, int num, vector<char>& result)
{
// 处理完最后一个字符,结束
if(*str=='\0')
return;
// num个字符的某个序列已经选取完,输出之
if(num==0)
{
vector<char>::iterator iter = result.begin();
for (; iter != result.end(); ++iter)
{
cout<<*iter;
}
cout<<endl;
return;
}
// num-1个字符的组合中包括当前字符,在剩下的串中选取num-1个字符的序列
result.push_back(*str);
Combination(str+1, num-1, result);
result.pop_back();
// num个字符的组合中不包括当前字符,在剩下的串中选取num个字符的序列
Combination(str+1, num, result);
}
void Combination(char* str)
{
if(!str) return;
int n = strlen(str);
vector<char> result;
for (int i = 0; i < n; ++i)
{
Combination(str, i+1, result);
}
}
如果要求的某一特定的组合,只需将函数中的for循环去掉,将i制定为你所求的特定值即可。
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
分析:我们首先以abc三个字符组成的字符串为例,分析其全排列的过程。
(1)固定第一个字符a,求后面两个字符bc的排列。
(2)将字符a和字符b交换,得到bac。固定第一个字符b,求后面两个字符ac的排列。
(3)现在需要将字符c放在第一个位置,固定第一个字符c。在(2)中我们已经将字符a和字符b交换了,为了保证字符c仍然是和初始时的第一个字符a交换,需要先将字符b和字符a交换回来,然后再将c和第一个位置的字符a交换,得到cba。固定第一个字符c,求后面两个字符ba的排列。
不难扩展到n个字符:
设n个字符的字符串S的全排列为Permutation(S); 设Si为不包括第i个字符,其它n-1个字符组成的字符串。(Si)Permutation(Si)表示第一个字符为Si的全排列。
当n>1时,字符串的全排列Permutation(S) 由(S1)Permutation(S1), (S2)Permutation(S2),...,(Sn)Permutation(Sn)构成。
当n=1时,字符串中只包括一个元素,不再需要排列,递归结束。
递归源码:
/*
题目:输入一个字符串,打印出该字符串中字符的所有排列。
例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、
bac、bca、cab和cba。
*/
void swap(char* a, char* b)
{
char tmp;
tmp = *a;
*a = *b;
*b = tmp;
}
void Permutation(char* str, int i, int n)
{
// 当前需要处理的元素只有最后一个的时候,表示处理结束,输出当前排列。
if(i == n)
printf("%s\n", str);
else
{
for (int j = i; j <= n; ++j)
{
//为避免生成重复排列,当不同位置的字符相同时不再交换
if(str[i] == str[j] && j != i)
continue;
swap(str+i, str+j);
Permutation(str, i+1, n);
swap(str+i, str+j);
}
}
}
/
// Get the permutation of a string,
// for example, input string abc, its permutation is
// abc acb bac bca cba cab
/
void Permutation(char* str)
{
if(!str)
return;
Permutation(str, 0, strlen(str)-1);
}