JDK源码中的String.indexOf是蛮力匹配的,可是JDK库的indexOf要比KMP快?算法不是让计算效率更高吗?JDK源码如下:
/**
* Code shared by String and StringBuffer to do searches. The
* source is the character array being searched, and the target
* is the string being searched for.
*
* @param source the characters being searched.
* @param sourceOffset offset of the source string.
* @param sourceCount count of the source string.
* @param target the characters being searched for.
* @param targetOffset offset of the target string.
* @param targetCount count of the target string.
* @param fromIndex the index to begin searching from.
*/
static int indexOf(char[] source, int sourceOffset, int sourceCount,
char[] target, int targetOffset, int targetCount,
int fromIndex) {
if (fromIndex >= sourceCount) {
return (targetCount == 0 ? sourceCount : -1);
}
if (fromIndex < 0) {
fromIndex = 0;
}
if (targetCount == 0) {
return fromIndex;
}
char first = target[targetOffset];
int max = sourceOffset + (sourceCount - targetCount);
for (int i = sourceOffset + fromIndex; i <= max; i++) {
/* Look for first character. */
if (source[i] != first) {
while (++i <= max && source[i] != first);
}
/* Found first character, now look at the rest of v2 */
if (i <= max) {
int j = i + 1;
int end = j + targetCount - 1;
for (int k = targetOffset + 1; j < end && source[j]
== target[k]; j++, k++);
if (j == end) {
/* Found whole string. */
return i - sourceOffset;
}
}
}
return -1;
}
看过KMP(推荐阮一峰老师的《字符串匹配的KMP算法》)的就会有疑问为什么JDK源码中不用KMP算法实现?当然Stackoverflow上肯定会有人问。
最佳答案:
翻译一下:
KMP具有更好的最差情况性能,但实际上需要一点预计算(生成偏移量表)。它还需要初始内存分配,这也可能影响性能。
对于(假定)在相对较短的字符串中搜索的常见用例,KMP实际上可能比原始实现要慢。
与此同时,对于真正庞大的数据集,你可能会使用比简单字符串更专门的数据结构,这意味着增加的实现(可能还有运行时)的成本,是不值得的投资。
标注一下这可能在未来的Java版本中发生变化,因为没有指定具体的算法。
KMP具体用到什么地方?面试!
只使用最基本的便利来实现判断字符串a是否被包含在字符串b中,
并且返回第一次出现的位置(找不到返回-1),算法效率尽量高,
不要使用indexOf、正则、substring、contain、slice等现成的方法
例如 a = '34';b = '1234567'; 返回2……
KMP算法适用的是Pattern中有重复的字串。但很多应用场景下,这种Pattern其实是不常见的。在平时开发场景中,一般都是短串匹配,蛮力匹配也就够了,脱离开发应用场景的算法就是耍流氓。