zoukankan      html  css  js  c++  java
  • 如何在文本编辑器中实现搜索功能? 字符串比较算法 BF算法 RK算法

    1.暴力比较 BF算法

    2.比较字串hash值 RK算法

    //字符串匹配
    public class StringCmp {
        //约定:A主串长 n ,B模式串 长m。要求:在A串中找到B串匹配的下标
        //
        //1.BF burst force 暴力比较,逐个字符比较
        //2.RK 以hash算法为主,比较字符串
    
        //1.BF  时间复杂度 O(n*m)
        //在A中进行 A[0,n-m] 范围内的 n-m+1 次的 m个字符比较
        //平时最容易理解的方式
        public static int BF(char[] a, char[] b) {
            for (int i = 0; i < a.length - b.length + 1; i++) {
                for (int j = 0; j < b.length; j++) {
                    if (a[i + j] != b[j])
                        break;
                    else if (j + 1 == b.length)
                        return i;
                }
            }
            return -1;
        }
    
       //2.RK 算法
    static final int R = 256; //26进制 static long[] RpowN = new long[4]; static boolean inited; //在A串中 从一个起始位置i,选取 A[i]~A[i+m] 共m个字符,计算其hash值(h1) i+m 不超过A的最大长度,也就是 i = [0,n-m] 范围 //hash算法为 字符的取值个数,如只考虑a-z,共26个字母,算作R进制(26进制),那么一个3个字符的字符串的hash为 a1*R^2 + a2*R^1 + a3*R^0 (a1为高位,a3为低位) //随着 i自增1,向后移动一个起始位置后,还是做同样的hash计算(h2) //此时发现有规律 h2=(h1-a1*R^m-1)* R + a4*R^0 //所以把A扫一遍计算 hash,在对每次算到的hash和 hashB 比较,一致说明有字符串匹配,如果考虑hash碰撞,则再次挨个比较字符即可(BF算法) //时间复杂度 O(n) public static int RK(char[] a, char[] b) { int m = b.length; RKinit(m); long hashB = RKHash(b, 0, m); long[] hashA = new long[a.length - b.length + 1]; hashA[0] = RKHash(a, 0, m); if (hashA[0] == hashB) return 0; for (int i = 1; i < hashA.length; i++) { hashA[i] = (hashA[i - 1] - (a[i - 1] * RpowN[m - 1])) * R + a[i + m - 1]; if (hashA[i] == hashB) return i; } return -1; } private static void RKinit(int blen) {//初始化R的N次方的缓存表,之后直接根据[N]做下标查询,比每次计算效率更高 long[] tmp; int startI = 2; if (blen > RpowN.length) { tmp = new long[blen]; startI = RpowN.length; RpowN = tmp; System.arraycopy(RpowN, 0, tmp, 0, RpowN.length); inited = false; } if (inited == false) { RpowN[0] = 1; RpowN[1] = R; for (int i = startI; i < RpowN.length; i++) RpowN[i] = (long) Math.pow(R, i); inited = true; } } public static long RKHash(char[] a, int off, int len) { long hashR = 0; for (int i = 0; i < len; i++) { //从高位到低位 a1*R^len + a2*R^len-1 + ....alen*R^0 hashR += RpowN[len - i - 1] * a[off + i]; } return hashR; } public static void main(String[] args) { char[] a = "abcdefg".toCharArray(); char[] b = "def".toCharArray(); System.out.println("BF(a,b) " + BF(a, b)); System.out.println("RK(a, b) " + RK(a, b)); } }
    BF(a,b) 3
    RK(a, b) 3
  • 相关阅读:
    《Django By Example》第十二章(终章) 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十一章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第十章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第九章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第八章 中文 翻译 (个人学习,渣翻)
    《Django By Example》第五章 中文 翻译 (个人学习,渣翻)
    我的superui开源后台bootstrap开发框架
    LayoutInflater 总结
    Android屏幕分辨率概念(dp、dip、dpi、sp、px)
    android studio安装问题
  • 原文地址:https://www.cnblogs.com/cyy12/p/11932989.html
Copyright © 2011-2022 走看看