字符串匹配算法

//思路一:时间复杂度为O(mn),返回第一个找到的匹配的下标。如果找不到匹配的结果,那么返回
public class MatchString {
   public int matchString(char[] old,char[] now,int pos){
       //返回第pos个元素开始的子串的第一个匹配的字符串。
       if(old==null||now==null)
           return -1;
       int len1=old.length;
       int len2=now.length;
       int i=pos,j=0;
       while((i+j)<len1&&j<len2){
           if(old[i+j]==now[j])
               j++;
           else{
               i++;
               j=0;
           }
       }
       if(j!=len2)
           return -1;
       
       return i;
   }
   public static void main(String[] args){
       String a="afghghj";
       char[] old=a.toCharArray();
       String b="gh";
       char[] now=b.toCharArray();
       MatchString matchString=new MatchString();
       int pos=matchString.matchString(old, now,0);
       System.out.println(pos);
   }
}

KMP算法

/*定义:

(1)next[0]= -1 意义:任何串的第一个字符的模式值规定为-1。
(2)next[j]= -1   意义:模式串T中下标为j的字符,如果与首字符
相同,且j的前面的1—k个字符与开头的1—k
个字符不等(或者相等但T[k]==T[j])(1≤k<j)。
如:T=”abCabCad” 则 next[6]=-1,因T[3]=T[6]
(3)next[j]=k    意义:模式串T中下标为j的字符,如果j的前面k个
字符与开头的k个字符相等,且T[j] != T[k] (1≤k<j)。
                       即T[0]T[1]T[2]。。。T[k-1]==
T[j-k]T[j-k+1]T[j-k+2]…T[j-1]
且T[j] != T[k].(1≤k<j);
(4) next[j]=0   意义:除(1)(2)(3)的其他情况。*/
/*意义:
 next 函数值究竟是什么含义,前面说过一些,这里总结。
设在字符串S中查找模式串T,若S[m]!=T[n],那么,取T[n]的模式函数值next[n],
1.       next[n]= -1 表示S[m]和T[0]间接比较过了,不相等,下一次比较 S[m+1] 和T[0]
2.       next[n]=0 表示比较过程中产生了不相等,下一次比较 S[m] 和T[0]。
3.       next[n]= k >0 但k<n, 表示,S[m]的前k个字符与T中的开始k个字符已经间接比较相等了,下一次比较S[m]和T[k]相等吗?
4.       其他值,不可能。*/
public class KMP {
    public int indexKMP(String old,String now,int pos){
        if(old==null||now==null)
            return -1;
        char[] oldStr=old.toCharArray();
        char[] nowStr=now.toCharArray();
        int len1=oldStr.length;
        int len2=nowStr.length;
        int[] next=getNext(now);
        int j=0;
        int i=pos;
        while(i<len1){
            if(j==-1||oldStr[i]==nowStr[j]){
                i++;
                j++;    
            }
            else
                j=next[j];//回退的位置。
            if(j==len2)
                return j-i;
            }
        return -1;
    }
    public int[] getNext(String s){
        char[] chars=s.toCharArray();
        int len=chars.length;
        int[] next=new int[len];
        next[0]=-1;//第一个数默认为-1;
        int k=-1;
        int i=0;
        while(i<len-1){
            if(k==-1||chars[k]==chars[i]){
                k++;
                i++;
                if(chars[k]!=chars[i])
                    next[i]=k;
                else
                    next[i]=next[k];//当后面一个数和前面一个数相同的时候
            }
            else
                // 比较到第K个字符,说明p[0——k-1]字符串和p[j-k——j-1]字符串相等,而next[k]表示
                // p[0——k-1]的前缀和后缀的最长共有长度,所接下来可以直接比较p[next[k]]和p[j]
                k=next[k];
        }
        return next;
    }
    public static void main(String[] args){
        String s="abcabd";
        String s1="aacaad";
        String s2="aaaaad";
        String old="ietoerabcabddkd";
        int[] a=new int[s.length()];
        KMP kmp=new KMP();
        a=kmp.getNext(s);
        int index=kmp.indexKMP(old, s, 0);
        for(int i:a){
            System.out.print(i+" ");
        }
        System.out.println(index);
    }
}

 

posted @ 2015-09-23 13:08  lisahappy  阅读(242)  评论(0编辑  收藏  举报