【问题标题】:Can someone explain this code? Permutation code [closed]有人可以解释这段代码吗?排列代码[关闭]
【发布时间】:2012-11-23 23:27:19
【问题描述】:

我正在做一个项目。我在 Interwebz 上找到了有关排列的代码。我想用它作为编写我自己的代码的基础。但是,我真的不明白代码中发生了什么。谁能帮我解释一下代码到底在做什么?

public void permutations(String prefix, String s) {
    int n = s.length();
    if (n == 0)
        System.out.println(prefix);
    else {
        for(int i = 0; i < n; i++){
           permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));
        }
    }
}

【问题讨论】:

    标签: java recursion permutation


    【解决方案1】:

    这是一些非常令人困惑的代码,原因有两个:

    1. prefix 参数:您应该在第一个参数中使用空字符串调用此函数,例如 permutations("", "ab") 以打印 "ab" 的所有(两个)排列。
    2. 第二个参数中带有s.substring(0, i) + s.substring(i+1, n) 的递归调用:注意java 的String.substring(x,y)包含第y 个字符。所以这相当于通过 s 并删除了第 y 个字符。

    现在想想当你通过for循环时会发生什么:第一个参数变成"""a"连接,即"a",第二个参数变成s,第一个字符被删除,即"b"。在下一个递归子调用中,prefix 变为"ab",第二个参数变为空字符串""。所以基本情况n == 0 被命中,我们打印结果"ab"

    现在我们进入 for 循环的下一次迭代,i == 1。现在我们在递归子调用的第一个参数中传递"b",在第二个参数中传递"a"。在下一个递归子调用中,prefix 变为 "ba" 并且 s.length 为 0,所以再次使用基本情况:打印 "ba"

    它很聪明,但难以理解。

    【讨论】:

      【解决方案2】:

      p(String prefix, String s)s 中取出1 个字符并将其添加到prefix 并递归地继续直到s 为空。

      s.charAt(i), s.substring(0, i) + s.substring(i+1, n) 部分从s 中提取一个字符。 假设s = "Magic!"i = 3 然后charAt(i) = 'i's.substring(0, i) = "Mag"s.substring(i+1, n) = c!"。这会将Magic! 拆分为iMagc!。下次使用i = 4 循环时,将导致c + Magi!。因为它对s 中的每个字符都这样做,所以在递归步骤之一中每个字符都将位于前面。

      调用层次结构如下所示

                                        / p("ab", "c") - "abc"
                       /- p("a", "bc") x
                      /                 \ p("ac", "b") - "acb"
                     /
                    /                   / p("ba", "c") - "bac"
      p("", "abc") x ---- p("b", "ac") x
                    \                   \ p("bc", "a") - "bca"
                     \
                      \                 / p("ca", "b") - "cab"
                       \- p("c", "ab") x
                                        \ p("cb", "a") - "cba"
      
                       ^-- 1st for loop  ^- 2nd for      ^- 3rd one prints
      

      【讨论】:

        【解决方案3】:

        方法permutations 接受一个字符串prefix 和一个字符串s 作为其参数。 int 类型 n 被设置为字符串 s 的长度。 (字符串的长度是它包含多少个字符)。

        现在我们继续讨论if-else 语句。 if 语句是说,如果s 的长度为0,即s 是一个空白字符串并且不包含任何信息,那么我们只是将字符串prefix 打印到控制台。然后该方法将跳过else 部分并执行permutations 方法之后的代码。

        如果不满足if 语句的条件,我们将运行else 语句,对于字符串s 中的每个字符,我们将在末尾追加(添加)该字符的prefix,例如,如果prefix 最初是“hello”并且字符是“U”,我们将得到prefix 是“helloU”。在我们完成附加s 中的所有字符后,我们将使用结果作为新的prefix 字符串。

        对于另一个参数,字符串s,我们将参与字符串的一部分,从字符0(包括)到位置i(不包括)的字符。请注意,字符串索引从 0 开始,一直到 (字符串的长度 - 1)。我们还将字符串的一部分从位置 i + 1(包括)处的字符到字符串s 中的最后一个字符。我们将使用这个结果作为新的s 字符串。

        然后我们将再次调用该方法,然后如果满足else 条件,该方法将使用新定义的字符串再次执行。这将继续循环,直到不满足else 条件,此时该方法将停止运行,我们将继续执行下一段代码(如果存在)。

        【讨论】:

        • 如果您需要我澄清任何事情,请随时问我。
        【解决方案4】:

        permutations(prefix + s.charAt(i), s.substring(0, i) + s.substring(i+1, n));

        其实这个置换算法就是利用了

        的思想
        Switching current character with ith character.
        

        假设我们有一个字符串abc。所以它的排列是:

        abc, acb, bac, bca, cab, cba

        我们可以发现acb只是在abc中切换bc加上前缀a。而bca 只是在bac 中切换ca,前缀为b

        那我们就用同样的思路递归解决置换问题。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-11-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多