我正在浏览一个示例Java代码
打印给定String的所有可能排列(具有重复项) 包括在内)
以下是代码:
public class StringPermutationWithRepetition {
public static void main(String[] args) {
String dictionary = "ABC";
printPermutation(dictionary, "");
}
public static void printPermutation(String str, String stringToPrint) {
System.out.println("The permutation now is: "+stringToPrint);
if (str.length() == stringToPrint.length()) {
System.out.println(stringToPrint);
return;
}
for (int i = 0; i < str.length(); i++) {
printPermutation(str, stringToPrint + str.charAt(i));
}
}
}
以下是输出的一部分:
The permutation now is:
The permutation now is: A
The permutation now is: AA
The permutation now is: AAA
AAA
The permutation now is: AAB
AAB
The permutation now is: AAC
AAC
The permutation now is: AB
The permutation now is: ABA
ABA
问题:我无法理解输出的这一部分:
The permutation now is: AAA
AAA
The permutation now is: AAB
AAB
即。在实例的时候
stringToPrint = 'AA'
和str.charAt(i) = 'A'
再次对该函数进行递归调用:
printPermutation(str, stringToPrint + str.charAt(i));
输出结果为:
The permutation now is: AAA
AAA
和stringToPrint = 'AAA'
但是只要遇到return
并且循环再次开始:
return;
}
for (int i = 0; i < str.length(); i++) {
printPermutation(str, stringToPrint + str.charAt(i));
}
stringToPrint
的值会回落到'AA'
。那是为什么?
我有一种直觉,认为这与Java相关的地方 按值传递 而不是按引用传递。
答案 0 :(得分:1)
执行stringToPrint + str.charAt(i)
时,它会创建一个新的String,而不会修改stringToPrint的值。当然,在方法调用中,新stringToPrint的值是不同的,但这是在不同的范围。
答案 1 :(得分:1)
你可能误解了递归。在这种情况下,它类似于&#34; DFS&#34;,它可以进入第一个解决方案。当没有解决方案时,它会退一步。
printPermutation("ABC","")
---> printPermutation("ABC","A")
---> printPermutation("ABC","AA")
---> printPermutation("ABC","AAA")
---> (str.length() == stringToPrint.length()); //ends
---> printPermutation("ABC","AAB")
---> (str.length() == stringToPrint.length()); //ends
---> printPermutation("ABC","AAC")
---> (str.length() == stringToPrint.length()); //ends
---> printPermutation("ABC","AB")
---> printPermutation("ABC","ABA")
---> (str.length() == stringToPrint.length()); //ends
//etc
请记住,当你这样做时
for (int i = 0; i < str.length(); i++) {
printPermutation(str, stringToPrint + str.charAt(i));
}
它首先调用递归,然后在方法结束之前不执行任何操作,因此它会保持打开状态&#34;等等,不会增加任何东西。