无法理解字符串排列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
A2
与A2
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
。