题目:
输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则输出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab和cba。
解决:
简单起见,字符串中没有相同的字符。
其实这是个递归的过程:对于字符串str,先分别逮住其中的每一个,如s,把它从str中踢开,成了 s + tr(下一次踢开t变为 t + sr),然后对于剩下来的,再从剩下的再次分别踢开一个加到左边的后面(假想被踢开的都在左边,剩下的都在右边哈),一直如此,直至右边都踢光了。算法如下:
void show(strL, strR) { if (strR不是空字符串) { for (对于strR中的每一个字符) { 把这个字符踢到strL的后面 递归show() } } else { 显示左边的字符串 } }
代码如下:
1 #include <iostream> 2 #include <string> 3 4 using std::cout; 5 using std::endl; 6 using std::cin; 7 using std::string; 8 9 //在这个过程中,把字符串分为左右两半,左边的字符已经固定,右边的可以组合出各种情况 10 //最后把左边固定的和右边各种情况一一连接,就是完整的各种字符串了 11 void show(string strL, string strR) 12 { 13 if (!strR.empty()) //右边的非空 14 { 15 for (int i = 0; i < strR.size(); i++) //对于每种情况 16 { 17 //注意要用左右字符串的副本 18 string tempL = strL; 19 string tempR = strR; 20 21 tempL.append(1, strR[i]); //把那个字符添加到左边字符串的后面 22 tempR.erase(i, 1); //右边的字符串中删除那个 23 show(tempL, tempR); //递归进行 24 } 25 } 26 else 27 { 28 cout << strL << endl; 29 } 30 } 31 32 int main(void) 33 { 34 string left; 35 string test("abcde"); 36 37 show(left, test); 38 cout << "------------------------------------ " << left << endl << test; 39 40 cin.get(); 41 }
结果:
总结:
递归的思想。
其实可以看做一棵树,从根节点开始分叉,每一个分叉是一种情况,最终到叶节点的高度为n,n为字符串长度,每个叶节点是一种情况。