递归调用中的参数

huangapple go评论65阅读模式
英文:

Parameters on call recursion

问题

public void seekFile(File file, int tab) {
    File[] files = file.listFiles();
    assert files != null;
    for (File file1 : files) {
        if (file1.isFile()) {
            for (int i = 0; i < tab; i++)
                System.out.print("|\t");
            System.out.println(file1.getName());
        } else {
            for (int i = 0; i < tab; i++)
                System.out.print("|\t");
            System.out.println(file1.getName());
            int index = tab + 1;
            seekFile(file1, index);
        }
    }
}

一开始,我使用了 seekFile(file1, ++tab) 进行递归,但是我得到的缩进都是错误的,在我将 tab 的位置替换为 ++tab 后,输出就变得正确了。为什么会这样呢?

英文:

I'm trying to use recursion to search for all the files and their sub-files in a folder. But I want to add indentation to make the output more beautiful. I added an int variable to the variable of the function to indicate how many indents are needed.This is the final code for success.

public void seekFile(File file, int tab) {
    File [] files=file.listFiles();
    assert files != null;
    for (File file1 : files) {
        if (file1.isFile()){
            for(int i = 0; i&lt; tab; i++)
                System.out.print(&quot;|\t&quot;);
            System.out.println(file1.getName());
        }else {
            for(int i = 0; i&lt; tab; i++)
                System.out.print(&quot;|\t&quot;);
            System.out.println(file1.getName());
            int index = tab+1;
            seekFile(file1,index);
        }
    }
}

At first, I used seekFile(file1, ++tab) to do a recursion, but the indentation I got was all wrong, and the output was accurate after I swapped out the tab. Why is that?

答案1

得分: 0

++tab有两个作用:

  • 求值为“比tab的值大1的值”
  • tab的值更改为上述值

实际上它做了更多的事情,但是为了理解问题中的代码,只需要知道这两个作用)

tab + 1有一个作用:

  • 求值为“比tab的值大1的值”

tab + 1不会改变tab的值。

这很关键,因为你不希望tab在每个递归调用中都发生变化。for (File file1 : files) 循环的每次迭代都应该使用相同的tab,因为每次迭代在相同目录中打印出一个文件/目录。只有在调用 seekFile 时,才会使用更大的 tab 值。

如果使用 ++tab,并且遇到一个目录,tab 将会递增,此后的每个兄弟文件/目录的缩进都会比应该的多。

如果使用 tab + 1,当前调用的 tab 不会改变。

在这两种情况下,“比tab的值大1的值”将传递给 seekFile 的下一个递归调用,并且会创建一个新的栈帧并推入调用栈。每个栈帧都有自己的 tab 变量,这就是为什么将 tab + 1 传递给新的调用不会影响当前调用中的 tab 变量。

英文:

++tab does two things:

  • evaluates to the value of "1 more than 'the value of tab'"
  • changes the value of tab to the above value

(It actually does a lot more things, but for the purpose of understanding the code in the question, just those two is enough)

tab + 1 does one thing:

  • evaluates to the value of "1 more than 'the value of tab'"

tab + 1 does not change the value of tab.

This is crucial, because you do not want tab to change within each recursive call. Every iteration of the for (File file1 : files) loop should use the same tab, because each iteration prints out a file/directory in the same directory. It is only when you call the seekFile, that you will use a higher tab number.

If you use ++tab, and you encounter a directory, tab will be incremented, and every sibling file/directory after that will have more indentation than it should.

If you use tab + 1, The tab for the current call doesn't change.

In both cases, the value of "1 more than 'the value of tab'" is passed to the next recursive call of seekFile, and a new stack frame is created and pushed onto the call stack. Each stack frame has its own tab variable, which is why passing tab + 1 to the new call doesn't affect the tab variable in the current call.

huangapple
  • 本文由 发表于 2020年9月26日 16:50:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/64075666.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定