我正在学习递归,并且在编写“简单”程序时遇到了问题。帮助将不胜感激。谢谢!代码编译没有语法错误,但我仍然无法用它来实现其目的。
我的已更新代码:
import java.io.*;
import java.util.*;
class recursion1
{
static Scanner inFile = null;
public static void main(String[] args) throws IOException
{
try
{
inFile = new Scanner(new File(args[0]));
}
catch (IOException e)
{
System.out.println("File may not exist");
}
reverse(inFile);
inFile.close();
}
public static void reverse(File inFile) throws IOException
{
String line = inFile.nextLine();
if (inFile.hasNextLine())
{
reverse(inFile);
}
System.out.println(line);
}
}
答案 0 :(得分:1)
以下是一般编写逆转程序的方法。我不是在给你Java,我给你的是“伪代码”。
function print_reverse(file)
local_variable line
line = read_from(file)
if (we are not at end of file)
print_reverse(file)
print line
因为line
是一个局部变量,所以每次调用print_reverse()
时都会得到一个新的实例。当您读入整个文件,并且想要反向打印行时,需要将行存储在某处。在这个递归函数中,一行存储一行,每次调用print_reverse()
一行。
我喜欢将递归函数视为“缠绕”,直到它们达到极限,然后在它们退出时“展开”。该限制被称为“基础案例”。使用任何递归函数,您需要清楚地了解您的基本情况。对于print_reverse()
,基本情况是在输入文件上命中文件的末尾。
在print_reverse()
遇到其基本情况后,它会停止递归调用自身;它会打印一条线然后展开。当每个递归调用结束时,它返回到先前的递归调用,然后依次打印其行并再次展开。这将持续到第一个调用打印其行并终止,此时递归完成并且所有行都已打印。
因此,总结一下:当“缠绕”时我们读取一行并保存它,基本情况是输入结束,当“展开”时我们打印一条保存的行。由于展开的顺序与缠绕的顺序完全相反,因此线条的顺序相反。
如果输入文件非常大,这个递归解决方案可能会耗尽所有可用的堆栈空间,在这种情况下程序将崩溃。如果你想编写一个可以处理任何大小的输入文件的文件反转程序,递归就行不通了。但是,看看这个程序是多么干净和简单。如果使用递归解决方案,一些问题更容易编码和理解。
反转文件非常容易;只需使用一个循环从文件中读取每一行,并将行附加到某种列表,然后在反向打印行中循环遍历列表。但是当你递归地编写它们时,其他程序非常简单,如果你不这样做,则会更加困难。例如,“河内之塔”拼图有一个非常干净的递归解决方案。
http://www.mathcs.emory.edu/~cheung/Courses/170/Syllabus/13/hanoi.html
答案 1 :(得分:0)
我对柜台的目的感到困惑。你递减它,但你永远不会评估任何形式的逻辑比较。我不认为这是不必要的,你只需要在用于打破递归循环的比较中使用它。递归需要一个调用递归函数的部分,另一个部分打破循环并开始退出递归调用的过程。