问题1 :输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
分析:可通过递归求解。递归算法的四个特性:(1)必须有可达到的终止条件,否则程序将陷入死循环;(2)子问题在规模上比原问题小;(3)子问题可通过再次递归调用求解;(4)子问题的解应能组合成整个问题的解。下面这个图很清楚的给出了递归的过程:
代码实现如下:
1 //函数功能 : 求一个字符串某个区间内字符的全排列 2 //函数参数 : pStr为字符串,begin和end表示区间 3 //返回值 : 无 4 void Permutation(char *pStr, int begin, int end) 5 { 6 if(begin == end - 1) //只剩一个元素 7 { 8 for(int i = 0; i < end; i++) //打印 9 cout<<pStr[i]; 10 cout<<endl; 11 } 12 else 13 { 14 for(int k = begin; k < end; k++) 15 { 16 swap(pStr[k], pStr[begin]); //交换两个字符 17 Permutation(pStr, begin + 1, end); //迭代 18 swap(pStr[k],pStr[begin]); //恢复 19 } 20 } 21
问题2:算法题:用你熟悉的编程语言,设计如下功能的函数:输入一个字符串,输出该字符串中所有字母的全排列。程序请适当添加注释。
C++函数原型:void Print(const char *str)
输入样例:abc
输出结果:abc、acb、bca、bac、cab、cba
分析:这个问题与上面问题1基本上是相同的,唯一不同的是这里要求函数的输入参数为const char*,所以不能直接进行操作,解决方法是重新定义一个辅助函数,用拷贝后的数组变化作为参数传入。
代码如下所示:
1 #include <iostream> 2 using namespace std; 3 4 static int count = 0; 5 6 void permut(char* a, int start, int end) 7 { 8 if(start >= end) 9 { 10 ++count; 11 cout << a << endl; 12 } 13 else 14 { 15 for(int i = start; i <= end; ++i) 16 { 17 swap(a[i], a[start]); 18 permut(a, start + 1, end); 19 swap(a[i], a[start]); 20 } 21 } 22 } 23 24 25 void Print(const char* str) 26 { 27 int len = strlen(str); 28 char *p = new char[len + 1]; 29 strncpy(p, str, len); 30 p[len] = '\0'; 31 permut(p, 0, len - 1); 32 delete [] p; 33 } 34 35 int main() 36 { 37
38 Print("abcd"); 39 cout << endl << "总共有 " << count << " 个" << endl; 40 return 0; 41 }