0

私の教授は、多くのことを行うプログラムを書くよう私たちに割り当てました。このプログラムが具体的に行うことの 1 つは、.txtファイルを調べて、指定した単語のすべてのインスタンスとそれらが配置されている行を返すことです。たとえば、これがテキスト ファイルの場合:

これはテストです。
ワードファイルのテスト。
これはテストと見なされます。

メソッドを実行して「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
}

では、これをどのように書けばよいのでしょうか。探している単語が何であるかを他にどのように知ることができるので、パラメーターに文字列を使用する必要があると思います。または、私が間違っているかもしれません。

4

2 に答える 2

1

まず第一に、再帰を使用してこの問題を解決する必要がある理由を尋ねる必要があります。Introduction to Computer Science - Javaページでは、再帰的なソリューションを説明するいくつかの特徴を見つけることができます:

  1. 解決策と戻り値がある単純な基本ケース。
  2. 問題をベースケースに近づける方法。つまり、問題の一部を切り取って、やや単純な問題にする方法です。
  3. 単純な問題をメソッドに戻す再帰呼び出し。

私にとって、あなたの問題はこの特性とはまったく一致しません。

しかし、OK、あなたはこの方法でそれをしたくありません - あなたはしなければなりません.

まず、問題を表すことができるモデルについて考える必要があります。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すべてのファイル コンテンツを表すことができる raw を提供できます。
于 2013-03-10T02:12:58.127 に答える
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);

     }
}
于 2013-03-10T01:54:40.623 に答える