2013-03-10 61 views
0

我的教授给了我们一个任务来编写一个执行很多事情的程序。具体的这个程序中的一件事是通过一个.txt文件,并返回你指定的单词的所有实例和它们所在的行。例如,如果这是文本文件:如何编写一个递归方法来返回包含令牌的文件中的所有行字符串

这是一个测试。
测试word文件。
这将被视为测试。

运行方法和搜索词后,“测试”,你应该接收回来的东西,如:

1: This is a test.  
3: This will be considered a test. 

现在,这是我的问题。他希望我们用递归方法来做,而且我不知道如何启动该方法。我知道一个递归方法,你必须调用它自己并减少每次你调用它,但是,这个方法的参数是一个单词。说我有:

String getTheWord (String word) {  
    if (word == 0){ //which still wouldn't compile, so I think I should use word == null  
     // something  
    } 

    //something smart here  

    return getTheWord(word - 1); // which wouldn't compile 
} 

那么我应该怎么写呢?我想我必须使用一个字符串作为参数,因为我怎么才能知道我要找的字是什么?或者,也许我错了,任何帮助!

+1

“家庭作业”可能不是标签的好主意。 – melvynkim 2013-03-10 01:25:47

+0

首先解释'getTheWord()'的作用。 – 2013-03-10 01:25:58

+0

另外,将字符串与int值0进行比较意味着什么?你如何从一个字符串中减去1? (这些是你的代码不能编译的原因,但是要弄清楚如何解决这些问题,你需要回答我以前的问题。) – 2013-03-10 01:27:06

回答

1

尝试类似:

public String getTheWord(String textToSearch, String searchingFor, 
    int currentLineNumber) { 

    // Separate the text into lines. 
    String[] lines = textToSearch.split('\n'); 

    // Get the first line of the (remaining) text. 
    String firstLine = lines[0]; 

    // We're going to have some result from this method call: either 
    // an empty string or a message indicating that we found the word. 
    String resultFromThisLine = "";   

    // Now, look for the word. 
    if (firstLine.contains(searchingFor)) { 
     // We found it. 
     resultFromThisLine = currentLineNumber + ": " + firstLine + "\n"; 
    } 

    // Now we check to see if there are any lines left. 
    if (lines.length == 1) { 
     // This was the last line. 
     return resultFromThisLine; 
    } else { 
     // There are more line(s). 
     // Create a string with all lines but the first one. 
     String remainingLines = ""; 
     for (int i=1; i<lines.length; i++) { 
      remainingLines += lines[i] + "\n"; 
     } 


     // Here's the key part. 
     // Take the result from this line, add it to the result from the 
     // next line, and return *that*. 

     return resultFromThisLine + getTheWord(remainingLines, searchingFor, 
      currentLine + 1); 

    } 
} 
+0

嗯,这完全比我预期的要多得多,但非常感谢。这使得问题在处理字符串时更易于理解和知道如何处理递归。非常感谢你。 – 2013-03-10 02:00:21

1

首先我们要问,为什么我们要使用递归解决这个问题的。在Introduction to Computer Science - Java页面,我们可以发现一些特点,它描述递归解决方案:

  1. ,我们有一个解决方案和一个返回值的简单的基本情况。
  2. 让我们的问题更接近基本案例的一种方法。即一种方式 砍掉问题的一部分,以得到一个更简单的问题。
  3. 递归调用将简单问题传递回 方法。

对我来说,你的问题根本不符合这个特性。

但是,好吧,你不想这样做 - 你必须。

首先你应该考虑模型,它可以代表你的问题。我创建了简单的Line类,它存储行号和行。

class Line { 

    private int number; 
    private String text; 

    public Line(int number, String text) { 
     this.number = number; 
     this.text = text; 
    } 

    public int getNumber() { 
     return number; 
    } 

    public String getText() { 
     return text; 
    } 

    @Override 
    public String toString() { 
     return number + " : " + text; 
    } 
} 

然后,你应该使用简单循环创建解决方案。

class LoopSearcher { 

    public List<Line> findLines(String text, List<String> lines) { 
     List<Line> matchLines = new ArrayList<Line>(); 
     int index = 0; 
     for (String line : lines) { 
      index++; 
      if (line.contains(text)) { 
       matchLines.add(new Line(index, line)); 
      } 
     } 
     return matchLines; 
    } 
} 

您可以用这种方式进行测试:

List<String> lines = IOUtils.readLines(new FileInputStream(new File(
     "D:/test.txt"))); 

List<Line> loopLines = new LoopSearcher().findLines("test", lines); 

for (Line line : loopLines) { 
    System.out.println(line); 
} 

现在,我们有循环的解决方案,我们可以修改成递归解决方案:

class RecursiveSearcher { 

    LinkedList<Line> matchLines = new LinkedList<Line>(); 

    public List<Line> findLines(String text, List<String> lines) { 
     if (lines.isEmpty()) { 
      return matchLines; 
     } 

     int number = lines.size() - 1; 
     String line = lines.remove(number); 
     if (line.contains(text)) { 
      matchLines.addFirst(new Line(number + 1, line)); 
     } 
     return findLines(text, lines); 
    } 
} 

你可以测试它这样:

List<String> lines = IOUtils.readLines(new FileInputStream(new File(
     "D:/test.txt"))); 

List<Line> recursiveLines = new RecursiveSearcher().findLines("test", 
     lines); 
for (Line line : recursiveLines) { 
    System.out.println(line); 
} 

就像你看,我有创建方法与将参数:

  1. 文本 - 文本,我们要在每行找到
  2. 线 - 文件中的所有行的列表。当然,您可以提供原始String,它可以表示所有文件内容。
相关问题