• 关于KMP算法


    KMP算法的重点在于:当某一个字符与主串不匹配时,我们应该知道把指针j移动到哪里

    // next[j] = k,表示当T[i] != P[j]时,j指针的下一个位置
    public static int[] getNext(String ps) {
    
        char[] p = ps.toCharArray();
    
        int[] next = new int[p.length];
    
        next[0] = -1;
    
        int j = 0;
    
        int k = -1;
    
        while (j < p.length - 1) {
    
           if (k == -1 || p[j] == p[k]) {
    
               next[++j] = ++k;
    
           } else {
    
               k = next[k];
    
           }
    
        }
    
        return next;
    
    }
    

    鉴于KMP算法略晦涩,所以去看了Java中String的indexOf方法,意外发现居然是暴力破解法:

    /**
         * 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;
        }
    

    于是又百度了一下,这样做可能的原因如下:
    原来JDK的编写者们认为大多数情况下,字符串都不长,使用原始实现可能代价更低。因为KMP和Boyer-Moore算法都需要预先计算处理来获得辅助数组,需要一定的时间和空间,这可能在短字符串查找中相比较原始实现耗费更大的代价。而且一般大字符串查找时,程序员们也会使用其它特定的数据结构,查找起来更简单。这有点类似于排除特定情况下的快速排序了。不同环境选择不同算法。

  • 相关阅读:
    OpenCV 限制对比度 图像增强
    2000 * 1000的图像截取大小为20 * 20
    在opencv3中的机器学习算法练习:对OCR进行分类
    OpenCV KNN加载训练好的模型
    OpenCV KNN数字分类
    vim简易配置
    shell简明笔记
    命令行关闭和开启ubuntu图形界面
    忘记Oracle数据库中sys等密码的解决方法
    Oracle常见练习题(2020082201)
  • 原文地址:https://www.cnblogs.com/jieyuefeng/p/10680523.html
Copyright © 2020-2023  润新知