子字符串查找或匹配(暴力法,KMP)

子字符串查找或匹配(暴力法,KMP)

字符串的一种基本操作就是子字符串的查找:给定一个长度为M的文本和一个长度为M的模式(pattern)字符串,在文本中找到一个和该模式相符的子字符串。通常情况下扩展为

  • 找出文本中所有与该模式相符的子字符串
  • 统计该模式在文本中出现的次数;
  • 找出上下文(和该模式相符的子字符串周围的文字)的算法

解决此类问题通用的方法有

  • 1.暴力子字符串查找法
    基本思想:定义指针i跟踪文本txt,另一个指针j跟踪模式。对于每个i,代码首先将j重置为0,并不断将它增大,直至找到一个不匹配的字符break;更新到下一个i,j重置。直到完全匹配(j==N)return i;或者全部文本遍历完成(return -1;)。

    
    //主函数
    public static void main(String[] args) {
        String txt = "ABACADABRACDEF";
        String pat = "CDEF";
        Solution so = new Solution();
        System.out.println(so.searchByForce(txt, pat));
        System.out.println(so.searchByForceCopy(txt, pat));
    }
    /*************************************/
    //暴力法1:时间复杂度-O(NM)
    public int searchByForce(String txt,String pat){
        int M = txt.length();
        int N = pat.length();
        for(int i=0;i<=M-N;i++){
            int j;
            for(j=0;j<N;j++)
                if(txt.charAt(i+j)!=pat.charAt(j))
                    break;
            if(j==N)
                return i;
        }
        return -1;  
    }
    

    另一种暴力法实现被称为显式回退。
    定义指针i跟踪文本,指针j跟踪模式;在指针文本的i和模式的j相匹配时(j++)i指向下一个txt;直到模式所有的匹配完成,j=N,返回查找成功,返回i-N+1;或者不相匹配时,i回退到i-=j,j重置为0。

    //暴力法另一种实现
    public int searchByForceCopy(String txt,String pat){
        int i,M = txt.length();
        int j,N = pat.length();
        for(i=0,j=0;i<M&&j<N;i++){
            if(txt.charAt(i)==pat.charAt(j))
                j++;
            else{
                i-=j;
                j=0;
            }
            if(j==N)
                return i-N+1;               
        }
        return -1;
    }
    
  • KMP(Kunth-Morris-Pratt子字符串查找算法)
    Kunth-Morris-Pratt发明的算法的基本思想是:当出现不匹配时,就能知晓一部分文本的内容(因为在二次匹配失败之前它们已经和模式相匹配)。我们可以利用这些信息避免将指针回退到所有这些已知的字符之前。

    原文作者:KMP算法
    原文地址: https://blog.csdn.net/nihaoxiaocui/article/details/52692997
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞