递归里面有 for 循环,感觉大脑维度不够用。请问大佬们,要怎么理解才好?

2019-11-01 17:11:54 +08:00
 taogen

如:字符串的排列

输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串 abc,则打印出由字符 a、b、c 所能排列出来的所有字符串 abc、acb、bac、bca、cab 和 cba。

void Permutation(char* pStr)
{
    if(pStr == nullptr)
        return;

    Permutation(pStr, pStr);
}

void Permutation(char* pStr, char* pBegin)
{
    if(*pBegin == '\0')
    {
        printf("%s\n", pStr);
    }
    else
    {
        for(char* pCh = pBegin; *pCh != '\0'; ++ pCh)
        {
            char temp = *pCh;
            *pCh = *pBegin;
            *pBegin = temp;

            Permutation(pStr, pBegin + 1);

            temp = *pCh;
            *pCh = *pBegin;
            *pBegin = temp;
        }
    }
}
1908 次点击
所在节点    程序员
6 条回复
yesterdaysun
2019-11-01 17:23:18 +08:00
abc 的全排列={a,b,c}开头+其他字符的全排列={a+bc 的全排列, b+ac 的全排列, c+ab 的全排列}

里面再继续递归, 终结条件就是递归到尾, 然后打印

for 里面 前面是遍历当前递归字符串的字符, 并分别替换到头部, 中间就是递归除了头部以外的部分, 后面是把开始的替换再换回来, 还原并进行下一步
taogen
2019-11-01 17:32:29 +08:00
@yesterdaysun 感谢大佬
dany813
2019-11-01 18:00:53 +08:00
有点懵逼
crclz
2019-11-01 18:02:22 +08:00
用树来理解。
打印 xx 排列本质上是对树的 dfs、bfs。用理解 dfs、bfs 的思路来理解排列,会很容易。假如不知道,请务必先学习 dfs、bfs。

假设第一步选定的是字母 a,那么接下来就是一个 dfs 过程:
这一层的 a 节点到树的下一层的节点,就只剩下去往 b c d e f...的边了。通往下一层的 a 的边已经不可用。
总结起来,下一层能选择的字母就是:之前未选择过的字母,也就是没出现在路径上的字母。
如果所有字母都用完了,那么意味着生成了一个排列。输出这个排列就是输出 dfs 的路径。
ungrown
2019-11-01 18:23:31 +08:00
脑袋不够用就要依靠外部存储器啊
咳咳
草稿纸,请
EminemW
2019-11-01 19:30:40 +08:00
其实这类全排列问题,或者说回朔算法的写法都差不多的。你多做几道就发现用一个模版就能解决

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/615343

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX