如何编写递归方法来返回包含标记String的文件中的所有行

时间:2013-03-10 01:23:04

标签: java recursion

我的教授给了我们一个编写程序的任务,该程序可以完成许多工作。具体的一点是,该程序通过.txt文件,返回您指定的单词的所有实例以及它们所在的行。例如,如果这是文本文件:

  

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

运行该方法并搜索单词“test”后,您应该收到类似的内容:

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
}

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

2 个答案:

答案 0 :(得分: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);

     }
}

答案 1 :(得分:1)

首先我们应该问,为什么我们应该使用递归来解决这个问题。在Introduction to Computer Science - Java页面中,我们可以找到一些描述递归解决方案的特征:

  1. 一个简单的基本案例,我们有一个解决方案和一个返回值。
  2. 让我们的问题更接近基本情况的一种方法。即一种方式 切掉部分问题以解决一个更简单的问题。
  3. 一个递归调用,将更简单的问题传递回 方法
  4. 对我来说,你的问题根本不符合这个特点。

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

    首先,您应该考虑模型,它可以代表您的问题。我创建了简单的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. text - 我们想要在每行中找到的文字
    2. lines - 文件中所有行的列表。当然,您可以提供原始String,它可以代表所有文件内容。