题目:

  输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串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 << "------------------------------------\n" << left << endl << test;
39 
40     cin.get();
41 }

   结果:




 

总结:

  递归的思想。

  其实可以看做一棵树,从根节点开始分叉,每一个分叉是一种情况,最终到叶节点的高度为n,n为字符串长度,每个叶节点是一种情况。

posted on 2014-08-19 11:49  简单的信仰  阅读(1222)  评论(0编辑  收藏  举报