【发布时间】:2016-12-14 17:21:22
【问题描述】:
我正在尝试将this code 修改为递归版本,以提高执行时间效率。代码所做的是在 Text 中查找所有模式的第一个索引并将它们添加到 ArrayList。我的代码如下:
public boolean search(String text, int n, String pattern, int d) {
if (n > text.length() || n < d) return true;
while (d >= 0 && d < pattern.length() && n < text.length() && text.charAt(n) != pattern.charAt(d)) d = next[d];
if (d == pattern.length()) {
(***) if (ans == null || !ans.contains(n-d)) ans.add(n-d);
n = n-d;
d = -1;
}
if( n < text.length() && n >= d ) search(text, n+1, pattern, d+1);
return false;
}
我的代码的循环版本:
public void search(String text) {
int m = this.pattern.length();
int n = text.length();
int i, j;
for (i = 0, j = 0; i < n && j < m; i++) {
while (j >= 0 && text.charAt(i) != this.pattern.charAt(j)) {
j = next[j];
}
j++;
if (j >= m) {
if (ans == null || !ans.contains(i-m+1) ) ans.add(i-m+1);
j = 0;
i = i - m + 1;
}
}}
更糟糕的是,它是指数级的,这就是我无法满足时间限制的原因。
数组next[] 与示例代码相同。我的问题是:
当参数文本字符串变大时,比如超过 2200 个字符,它总是引发
java.lang.StackOverflowError;特别是在括号内的三个星号的行中。即使只剩下ans.add(n-d),仍然是同样的问题。返回值boolean毫无意义,即使我将函数return类型更改为void并删除最后一行,它仍然是同样的问题。有没有更好的方法来做到这一点?
【问题讨论】:
-
是什么让您认为递归版本会更高效?它所能做的就是更慢。正如消息所说,您会遇到堆栈溢出(由于大量递归)。最好保留原代码。
-
感谢 Yves Daoust 的回复。通过使用最后第二个条件,我不必一直走到字符串末尾并在 n
-
原代码的一个问题是它总是超过时间限制,另一个是它只能得到一个模式索引,我需要在Text中找到所有模式的索引。
-
大部分代码对返回值没有影响,一旦超过第一个 if,返回值总是 false。
-
@TaoWang:使代码递归没有帮助。如果你想加速算法,看看经典的解决方案。en.wikipedia.org/wiki/String_searching_algorithm
标签: java string algorithm pattern-matching trie