2012-12-06 119 views
0

我正在开发一个项目。我发现这个关于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)); 
     } 
    } 
} 
+5

它被称为递归。 – jlordo

回答

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只是切换bcabc前缀a。而bca只是在bac中切换ca,前缀为b

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

2

permutations方法采用字符串prefix和String 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条件未满足,此时该方法将停止运行,并且我们将转到下一部分代码(如果存在)。

+0

如果您需要我澄清任何事情,请不要犹豫,问我。 – hologram

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。现在我们在递归subcall的第一个参数中传递"b",在第二个参数中传递"a"。在下一个递归subcall prefix变成"ba"s.length是0,所以基地案件再次:打印"ba"

它很聪明,但不可思议。

1

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 
相关问题