有人可以解释这段代码吗?排列代码

时间:2012-12-06 00:33:46

标签: java recursion permutation

我正在开展一个项目。我在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));
        }
    }
}

4 个答案:

答案 0 :(得分:2)

方法permutations将字符串prefix和字符串s作为参数。 int类型n设置为字符串s的长度。 (字符串的长度是它包含的字符数。)

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

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

对于另一个参数,字符串prefix,我们将使用字符串的一部分,从字符0(包括)到位置s的字符(不包括)。请注意,String索引从0开始并向上移动(String的长度为-1)。我们还将字符串的一部分从位置i + 1(包括)的字符转换为字符串i中的最后一个字符。我们将使用此结果作为新的s字符串。

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

答案 1 :(得分: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

答案 2 :(得分:1)

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只是在b中使用前缀c切换abca。而bca只是在c中使用前缀a切换bacb

然后我们只是使用相同的想法来递归地解决排列问题。

答案 3 :(得分:1)

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

  1. prefix参数:您应该在第一个参数中使用空字符串调用此函数,例如permutations("", "ab")以打印"ab"的所有(两个)排列。
  2. 在第二个参数中使用s.substring(0, i) + s.substring(i+1, n)进行递归调用:请注意,java的String.substring(x,y)包含第y个字符。所以这相当于传递s并删除了第y个字符。
  3. 现在想想当您逐步执行for循环时会发生什么:第一个参数变为"""a"连接,即"a",第二个参数变为{{ 1}}删除第一个字符,即s。在下一个递归子查询中,"b"变为prefix,第二个参数变为空字符串"ab"。因此基础案例""会被点击,我们会打印结果n == 0

    现在我们转到for循环的下一个迭代"ab"。现在我们在递归子句的第一个参数中传递i == 1,在第二个参数中传递"b"。在下一个递归子查询"a"变为prefix"ba"为0,因此再次基本情况:打印s.length

    这很聪明,但难以理解。