- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我写了一个代码来填充 KMP 的前缀表。这是这个 algorithm 的小变化.我无法说服自己这个算法/实现在 O(n) 时间内运行。我很难弄清楚第二次递归调用对总运行时间的影响。有帮助吗?
public void fillFailTable(int[] failTable,String p){
failTable[failTable.length-1] = preLength(failTable,p);
}
private int preLength(int[] failTable,String s){
if(s.length() == 1){
return 0;
}
int n = s.length();
int k = preLength(failTable,s.substring(0,n-1));
failTable[n-2] = k;
if(s.charAt(k) == s.charAt(n-1)){
return k+1;
}else{
return preLength(failTable,s.substring(n-1-k));
}
}
最佳答案
这实际上很有趣(我仍然想知道为什么没有比我更聪明的人回答这个问题)。请对这个解释持保留态度,因为我不是 100% 确定这是否接近正确(尽管我可以 100% 告诉你这个方法在 O(n) 中运行,因为这是他们在大学几年前,但他们并没有费心去解释它,呃,所以我不得不自己想出它)。
好吧,让我们从 s.length = 2 的一个非常基本的例子开始。事先要提到两件事:
我们首先进入第一个 preLength() 方法(我们称它为 *),现在用 s.length = 1 调用它并立即返回 0。现在因为我们只考虑最坏的情况(意思是 s .charAt(k) != s.charAt(n-1)) 我们输入第二个 preLength() 也是一个长度为 1 的字符串(因为 n=2 和 k=0)。这个也立即返回一个 0 给我们的 *。这结束了我们的方法调用。我们总共有 3 个方法调用。我们的 * 和两个 preLength()。这是一张图片:
现在让我们看一个起始 s.length = 3 的示例。正如您所注意到的,我们立即调用了 s.length = 2 的 preLength() 并且,从我们之前的示例中,我们知道这个需要 3 个方法调用。现在我们需要记住,当方法 preLength(2) 这次返回时,它返回到我们的原生 preLength(3),它现在将再次调用 preLength(2)(else 中的那个),这将再次需要 3 次方法调用。所以我们总共需要 2*3+1 次方法调用。这给了我们 7。同样,这里有一个图像(圆圈是 preLength 的调用,字符串的长度如圆圈所示):
现在您可以看到所有这些方法调用都是对称的 - 那是因为我们的 k
始终 等于 0,这意味着第二个 preLengt() 将是使用与第一个相同大小的字符串调用 - 当我们知道 需要多少个时,我们可以看到
因为 s.length = m
需要多少个m-1f(m) = 2*f(m-1)+1
其中 f(m)
是告诉我们有多少方法的函数我们需要为大小为 m
的字符串计算表的调用。这是有效的,因为正如我之前所说,方法调用是对称的(那是因为在最坏的情况下 k=0 总是并且 preLenght() 总是返回 0,因此 2* 并且我们需要添加 1 个方法调用,我们调用的第一个)。
所以基本上随着我们输入的每次增量(m
的大小),计算时间增长 2 倍加一 (2*m+1),据我所知,这意味着这种方法在最坏的情况下是情况,O(n)。
正如我所说,请对这个持保留态度,但我希望这是有道理的 :)
关于java - KMP前缀表运行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11819766/
KMP 算法实例详解 KMP算法,是由Knuth,Morris,Pratt共同提出的模式匹配算法,其对于任何模式和目标序列,都可以在线性时间内完成匹配查找,而不会发生退化,是一个非常优秀的模式匹配
我正在尝试使用搜索算法KMP来计算模式出现次数和所需比较(在下面的代码中称为匹配)。 我尝试执行以下操作: public class KMP { private String pat;
我想搜索一个字符串(假设a)在字符串b中出现了多少次。我想过实现 Knuth-Morris-Pratt 算法,但我更喜欢内置的 java 函数。有这样的功能吗?我希望该函数的复杂性尽可能最低,因为我多
有人要求我了解 KMP DFA,我在书中找到的是该实现,但我们的讲师一直称其为“前缀函数”。我真的不明白这个功能是哪一部分,有人可以给我解释一下吗?很抱歉,如果有人在某个地方问过这个问题,但我找不到。
我正在尝试使用 CLRS 实现 KMP 字符串匹配算法,但是文本输入为“bbaa”,模式输入为“aab”,它陷入了 while 的无限循环在 getKMPPrefix 函数中循环。我的代码如下: pr
KMP 算法在最佳情况下的最少比较次数是多少? 最佳答案 最好的情况是您要查找的字符串刚好位于文本字符串的开头。在这种情况下,如果您要在 n 字母字符串中查找 k 字母字符串,则最好的比较次数是 k。
我已经实现了用于在字符串 B 中搜索字符串 A 的 Knuth-Morris-Pratt 算法。如果找到字符串,则返回字符串的第一个位置,否则返回 -1。但是现在我想统计字符串 A 在字符串 B 中的
最近学习了KMP字符串匹配算法,差不多搞定了。但我不明白的是如何在 O( length_of_pattern ) 中构建故障函数。我不需要代码,如果可能,我需要一个清晰的解释。提前致谢! 最佳答案 来
想知道是否有人可以提供一些关于选择 KMP 和后缀树之间的利弊的建议,如果我们想看看一个字符串是否是另一个字符串的子字符串?谢谢。 提前致谢,林 最佳答案 运行时和内存复杂度大致相同。您在 O(N)
如我所见,在 KMP 中构建故障/前缀表的主要函数(在所有在线资源中,甚至在这个 answer _ 中,如下所示: int j = 0; for (int i = 1; i 0 && pa
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
扩展kmp既是求模式串和主串的每一个后缀的最长公共前缀 即令s[i]表示主串中以第i个位置为起始的后缀,则B[i]表示s[i]和模式串的最长公共前缀 显然KMP是求s[i]=模式串长度的情况,所
先声明,本人菜鸟一个,写博客是为了记录学习的过程,以及自己的理解和心得,可能有的地方写的不好,希望大神指出。。。 抛出问题 给定一个文本串test_str(被匹配的字符串)和模式串pat_str
恐怕现在用过电脑的人,一定都知道大部分带文本编辑功能的软件都有一个快捷键ctrl+f 吧(比如word)。这个功能主要来完成“查找”,“替换”和“全部替换”功能的,其实这就是典型的模式匹配的应用,即
我想统计一篇文章的词频。 我的想法是先创建一个struct数组 struct{ char[WORD_SIZE] }data[MAX_WORD_NUMBER]; 然后读取每个字符然后确
您好,我正在尝试编写 KMP search 的 C# 版本来自 C 书中的算法。无法找到我的算法中的缺陷。有人愿意帮忙吗? static int KMP(string p, string str) {
我想找到字符串 S 中与正则表达式 R 匹配的所有子字符串。正则表达式只能包含“.”和符号(其中“.”表示任何符号)。我正在尝试使用 KMP 来解决这个问题: 1) 构建字符串 T = R + '#'
从函数返回一个向量会产生什么问题吗?还是只是一些基本的语法问题? 这只是CLRS中的示例代码. computePrefix 函数计算给定模式的正确前缀的值,并匹配主函数中的值。 获取 SIGSEGV
我正在寻找一种有效的算法,以在将 pattern 与文本进行比较时允许不匹配(最多 3 个)。原始 KMP 在我的数据上有效地完成了这项工作,但正在考虑扩展该算法以适应不匹配情况。 对于我的情况:GA
我是一名优秀的程序员,十分优秀!