前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >KMP和String.indexOf

KMP和String.indexOf

作者头像
只喝牛奶的杀手
发布2019-08-26 17:48:57
1.9K0
发布2019-08-26 17:48:57
举报

JDK源码中的String.indexOf是蛮力匹配的,可是JDK库的indexOf要比KMP快?算法不是让计算效率更高吗?JDK源码如下:

代码语言:javascript
复制
/**
     * 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具体用到什么地方?面试!

代码语言:javascript
复制
  只使用最基本的便利来实现判断字符串a是否被包含在字符串b中,
  并且返回第一次出现的位置(找不到返回-1),算法效率尽量高,
  不要使用indexOf、正则、substring、contain、slice等现成的方法
  例如 a = '34';b = '1234567'; 返回2……

KMP算法适用的是Pattern中有重复的字串。但很多应用场景下,这种Pattern其实是不常见的。在平时开发场景中,一般都是短串匹配,蛮力匹配也就够了,脱离开发应用场景的算法就是耍流氓。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 只喝牛奶的杀手 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档