【Go+KMP】28. 找出字符串中第一个匹配项的下标

28. 找出字符串中第一个匹配项的下标

题解

动态规划之 KMP 算法详解

Go语言实现

核心

  • KMP其实就是dp变化,因此我们要让模式串pat产生相应的前缀影响的状态图
  • 后面只需让字符串txt跳进这个状态图进行比较
package main

import "fmt"

type KMP struct {
    
    
	dp  [][]int
	pat string
}

//创建一个模式串的状态图
func NewKMP(pat string) *KMP {
    
    
	k := &KMP{
    
    pat: pat}
	M := len(pat)
	//创建一个二维数组
	k.dp = make([][]int, M)
	for i := 0; i < M; i++ {
    
    
		//256表示ASCII,后面传入的是char,所以要强制转换
		k.dp[i] = make([]int, 256)
	}
	//初始状态
	k.dp[0][int(pat[0])] = 1
	//影子,表示最近的前缀
	X := 0
	for j := 1; j < M; j++ {
    
    
		for c := 0; c < 256; c++ {
    
    
			k.dp[j][c] = k.dp[X][c]
		}
		//符合下一个字符串,就要推进下一个状态
		k.dp[j][int(pat[j])] = j + 1
		//影子再次更新最近的前缀
		X = k.dp[X][int(pat[j])]
	}
	return k
}

func (k *KMP) Search(txt string) int {
    
    
	M, N := len(k.pat), len(txt)
	j := 0
	for i := 0; i < N; i++ {
    
    
		j = k.dp[j][int(txt[i])]
		if j == M {
    
    
			//返回第一索引
			return i - M + 1
		}
	}
	//找不到,返回-1
	return -1
}

func strStr(haystack string, needle string) int {
    
    
	k := NewKMP(needle)
	return k.Search(haystack)
}

func main() {
    
    
	haystack, needle := "sadbutsad", "sad"
	fmt.Println(strStr(haystack, needle))
}

猜你喜欢

转载自blog.csdn.net/kokool/article/details/129779251