我正在尝试将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
并删除最后一行,它仍然是同一个问题。
有没有更好的方法呢?
答案 0 :(得分:0)
目前,JVM(Hotspot)没有尾调用优化。所以每次递归都会消耗堆栈。所以你得到stackoverflow错误。目前坚持迭代方法会更好。