首先我们应该问,为什么我们要使用递归来解决这个问题。在Introduction to Computer Science - Java页面中,我们可以找到一些描述递归解决方案的特征:
- 一个简单的基本案例,我们有一个解决方案和一个返回值。
- 一种使我们的问题更接近基本情况的方法。即一种切掉部分问题以获得更简单的问题的方法。
- 将更简单的问题传递回方法的递归调用。
对我来说,你的问题根本不符合这个特征。
但是好吧,你不想这样做——你必须这样做。
首先你应该考虑模型,它可以代表你的问题。我创建了简单的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);
}
如您所见,我创建了带有 to 参数的方法:
- text - 我们要在每一行中找到的文本
- 行 - 文件中所有行的列表。当然,你可以提供 raw
String
,它可以代表所有文件内容。