递归数组遍历:代码相似却输出结果不同的原因分析
我写了两个递归遍历数组的Java程序,第一个能实现数组倒序输出,但第二个本该倒序的程序却输出了正序,二者代码看似一致,请问原因是什么?
程序一(倒序输出)
public class SomeClass2 { public static String someMethod(int[] array2, int x) { if (x < array2.length) return String.format("%s%d ", someMethod(array2, x + 1), array2[x]); else return ""; } public static void main(String[] args) { int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; String results = someMethod(array, 0); System.out.println(results); } }
程序二(正序输出)
import java.util.Scanner; public class BackwardsArray { public static String reverse(char[] array, int x) { if (x < array.length) return String.format("%s " + reverse(array, x + 1), array[x]); else return ""; } public static void main(String[] args) { Scanner input = new Scanner(System.in); System.out.print("Enter a sentence: "); String sentence = input.nextLine(); char[] charArray = sentence.toCharArray(); String backwardsSentence = reverse(charArray, 0); System.out.println(backwardsSentence); } }
核心差异分析
问题出在String.format的参数逻辑和字符串拼接的位置:
程序一中,
String.format("%s%d ", someMethod(array2, x + 1), array2[x])的逻辑是:先递归调用someMethod(x+1)拿到后续元素的倒序结果,再把当前元素array2[x]拼在这个结果的后面。递归执行时会先深入到数组最后一个元素(比如x=9时,先调用x=10返回空字符串,再返回"" + "10 "),接着x=8返回"10 " + "9 ",以此类推,最终输出10 9 8 ... 1,实现倒序。程序二中,
String.format("%s " + reverse(array, x + 1), array[x])的逻辑完全相反:这里是先递归调用reverse(x+1)拿到后续结果,然后把这个结果直接拼在格式串"%s "的后面,再用当前元素array[x]替换格式串里的%s。比如x=0时,先拿到x=1到末尾的正序结果,再把当前元素array[0]放在最前面,最终输出元素0 元素1 元素2 ... 元素n,变成了正序。
简单说,程序一是先拿后面的结果,再追加当前元素;程序二是先放当前元素,再追加后面的结果,顺序完全颠倒了。
如果要修复程序二,只需要把递归调用放在format的参数里,而非格式串拼接,改成:
return String.format("%s%c ", reverse(array, x + 1), array[x]);
这样逻辑就和程序一一致,就能输出倒序了。
内容的提问来源于stack exchange,提问作者stupidmoron

