zoukankan      html  css  js  c++  java
  • 让我们来写个算法吧,(3)字符串匹配之KMP算法

       字符串的匹配是非常常用的一项技术,我们来思考下面一个场景

       现在有给定字符串 ABCDEFGABCDA

         匹配字符串 ABCDA

      我们按照一般思路,暴力匹配。于是得出了以下的代码

       

    public int bfSearch(String txt ,String pat) {
            
            int tLen = txt.length();
            int pLen = pat.length();
            int i ;
            int j ;
            for ( i = 0; i < tLen; i++) {
                for ( j = 0; j < pLen && i< tLen; j++) {
                    if(txt.charAt(i) == pat.charAt(j)) {
                        i++;
                    }else {
                        break;
                    }
                }
                if(j == pLen) {
                    return  i -j;
                }else {
                    i = i-j;
              j = 0; } }
    return -1; }

       此方法可以实现,但是有个效率上的问题就是,第一次匹配 i=0 到上串ABCDE 与下串ABCD ,我们认为匹配失败,上串的i 下标返回到2继续匹配,但是我们已经知道前4个已经匹配过不用再次匹配。所以我们有没有一种算法可以回溯 i 下表到第5位呢???

      由此大名鼎鼎的KMP算法就由此引出来了,如何让i下标不回溯,只跑 j 下标呢。核心就是引出一个 next [] 用来记录j下标的回溯策略。具体的原理和思路本人不再阐述给你们几篇写的好的连接

      https://www.cnblogs.com/zhangtianq/p/5839909.html

      我们这边直接上代码 

      

        public int kmpSearch(String txt , String pat) {
            
            int tLen = txt.length();
            int pLen = pat.length();
            int [] next = getNext(pat);
            for (int i : next) {
                System.out.print(i+" ");
            }
            System.out.println();
            int i = 0;
            int j = 0;
            while(i < tLen) {
                System.out.println("第 "+i+" 次 i= " +i +" ,j= "+j);
                if(j == -1 || txt.charAt(i) == pat.charAt(j)) {
                    ++i;
                    ++j;
                }else {
                    j = next[j];
                }
                
                
            }
            
            
            return j == pLen ? i-j : -1;
        }
        
        public int[] getNext(String pat) {
            
            int length = pat.length();
            int [] next = new int[length];
            
            next[0] = -1;
            
            int k= -1;
            int j = 0;
            
            while(j<length-1) {
                
                if(k==-1 || pat.charAt(k) == pat.charAt(j)) {
                    ++k;
                    ++j;
                    next[j]=k;
                }else {
                    k = next[k];
                }
                
            }
            return next;
        }

      主要在于求出next数组,让i指针不回退,只用寻找j指针的回推策略。

  • 相关阅读:
    游戏热更思路
    Shader实现新手指引挖空圆形和矩形
    C#利用栈实现字符串运算解析
    Unity UGUI和特效(含粒子系统和3D Object)之间层级问题
    Unity中的值传递与引用传递
    Unity3D中的线程与协程
    进程、线程、协程、CPU
    Photon Server与Unity3D客户端的交互
    Photon Server的Unity3D客户端配置
    Photon Server的服务器端配置
  • 原文地址:https://www.cnblogs.com/leaveast/p/12404950.html
Copyright © 2011-2022 走看看