美文网首页
009 go 语言 实现 KMP 模式匹配算法

009 go 语言 实现 KMP 模式匹配算法

作者: 愚蠢的二师弟 | 来源:发表于2020-04-06 20:48 被阅读0次

    KMP 算法

    参考资料
    B站, 印度小哥写的 汪汪都能看懂的KMP算法
    印度小哥的代码的github地址

    建议多看几遍

    本来写了点, 但是觉得写得不好, 又没图, 所以还是删了。

    下面是go 语言实现的代码

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        mainString :="abcxabcdabxabcdabcdabcy"
        // subString := "abcdab";
        // subString :="abcdabc"
        subString :="abcdabcy"
        next := computeNextArray(subString);
        fmt.Println("next----", next)
        idx := KMP(mainString, subString);
        fmt.Println("子串在主串中第一次出现的位置", idx)
    }
    
    
    /**
    KMP 
    **/
    func  KMP(mainString string, subString string) int{
        mainIdx :=0;
        subIdx :=0;
        mainLen :=len(mainString)
        subLen := len(subString)
        next := computeNextArray(subString);
        for  {
            if mainIdx>=mainLen  || subIdx >= subLen{
                //当子串匹配完, 说明主串中包含子串, 需要结束
                //当主串匹配完, 不管子串有没有结束, 都应该不再匹配
                break;
            }
    
            if mainString[mainIdx] == subString[subIdx]{
                //字符匹配的时候, 主串和子串都往后走
                mainIdx ++;
                subIdx ++;
            }else{
                //不相等的时候, 子串切换到next数组中对应的前一个元素对应的, 需要位移的下标, 进行重新匹配
                if subIdx != 0{
                    subIdx = next[subIdx-1]
                }else{
                    //当主串元素与子串元素不一样, 且子串回退到了首字符时, 检查主串的下一个字符
                    mainIdx++
                }
    
            }
        }
    
        //判断结果
        if subIdx>=subLen{
            //说明子串匹配完了, 子串在主串中存在
            return mainIdx - subLen
        }
        //其他情况下, 说明子串没走完, 返回 -1
        return -1
    
    }
    
    
    
    //computeNextArray 用于计算子串的 next 数组
    func computeNextArray(subString string) []int {
        next := make([]int, len(subString))
        index :=0; 
        i := 1;
        for i < len(subString){
            if subString[i] == subString[index]{
                next[i] = index + 1
                i ++ ;
                index ++;
            }else{
                //不相等的时候
                if index != 0{
                    //当index != 0 的时候, 把 next 中, index 前一个元素对应的 next中的值, 赋给 index  
                    index = next[index -1]
                }else{
                    //当index = 0 的时候,  subString[i] 和 subString[0] , 也就是subString 首字母不相同, 则i向后走
                    i++
                }
            }
        }
        return next
    }
    
    
    
    

    相关文章

      网友评论

          本文标题:009 go 语言 实现 KMP 模式匹配算法

          本文链接:https://www.haomeiwen.com/subject/wjpsphtx.html