无法理解字符串排列Java代码

我有这个工作代码来打印字符串排列而不重复,但无法解决它如何在逻辑中工作。 任何建议都会非常有帮助。

private static void permutation(String input, String sofar) { if (input.equals("")) { System.out.println(count + " " + sofar); count++; } for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); if (input.indexOf(c, i + 1) != -1) continue; permutation(input.substring(0, i) + input.substring(i + 1), sofar+c); } } 

function调用:

 String input = "ABBCD"; permutation(input, ""); 

  for (int i = 0; i < input.length(); i++) { 

上面的for循环正在发挥魔力

输入ABCD

迭代

输入:BCD sofar:A ....递归继续

输入:ACD sofar:B ....

输入:ABD sofar:C ....

输入:ABC sofar:D .....

希望这可以帮助

请记住,递归通常是一个停止条件,并尝试使用递归调用解决一个较小的问题,假设递归有效。

我已经对代码进行了评论,因此您可以将其替换为您的副本,以便在您回复它时跟踪它正在执行的操作。 一旦理解就添加自己的评论,因为它们可以帮助您了解发生的情况:

第1部分:基本条件/停止条件:

 if (input.equals("")) { System.out.println(count + " " + sofar); count++; } 

这部分停止递归并返回一个结果,基本情况是一个空字符串,它有一个单独的排列也是一个空字符串。

第2部分:迭代较小的问题。

  for (int i = 0; i < input.length(); i++) { char c = input.charAt(i); // ... permutation(input.substring(0, i) + input.substring(i + 1), sofar+c); } 

此部分使用较小(按一个字符)字符串的递归调用来解决问题。 它调用相同的字符串,省略了它所生成的后续结果所依据的字符。 我们知道调用会产生所有排列(这是我们的假设)。 所以我们现在知道递归的作用。

第2.1部分:重复删除“if”:

这可能是这里最棘手的部分......

 if (input.indexOf(c, i + 1) != -1) continue; 

让我们弄清楚这一点。 这意味着:“尝试找到与所选角色相同的角色,如果存在,则跳过此迭代并生成解决方案”。

想想像“ABBA”这样的词,它会跳过第一个“A”和“B”,但不会跳过最后一个。 为什么? 那么,因为相似字符的顺序无关紧要(如果我们标记字符A1 B1 B2 A2 ,现在替换它们: A2 B2 B1 A1 ,这仍然是同一个单词,所以对于像“AA”这样的单词只有一个排列,因为A1 A2A2 A1相同。

获取最后一个字符更容易,因为我们不需要维护我们在此迭代中已经使用过的字符列表。

包含基本注释的完整代码:

 private static void permutation(String input, String sofar) { if (input.equals("")) { // this is the stop condition // the only permutation of "" is "" System.out.println(count + " " + sofar); // this counts how many permutations were outputted. count++; } for (int i = 0; i < input.length(); i++) { // this loop basically means "take every // possible character, and append permutations of all // other characters to it. char c = input.charAt(i); if (input.indexOf(c, i + 1) != -1) // this makes sure we only take a single "A" or "B" // character in words like "ABBA", since selecting // the same character would create duplicates continue; // this creates a new string without the selected character // and under the assumption the recursion works // appends all permutations of all other characters // to it permutation(input.substring(0, i) + input.substring(i + 1), sofar+c); } } 
 if (input.equals("")) { System.out.println(count + " " + sofar); count++; } 

由于输入不是""因此传递此步骤。 请注意,您可以在此处使用input.empty() 。 这里唯一要记住的是count没有增加。


 for (int i = 0; i < input.length(); i++) { 

这将循环input所有字符


 char c = input.charAt(i); if (input.indexOf(c, i + 1) != -1) 

这将检查下一个字符是否等于当前字符,如果是,则它将使用continue关键字直接跳转到下一个iteration (下一个字符)。


如果没有,那么它将调用方法(我们称之为recursivity ),传入字符串而不使用当前的char 。 但是让它重新回归。

 permutation(input.substring(0, i) + input.substring(i + 1), sofar+c); 

现在在输入为空的情况下,

将打印非独特character的计数+所有这些character