数据结构go语言实现(2)字符串与kmp算法

字符串与kmp算法

// Package string 模拟堆分配的字符串
package string

// String 堆分配的字符串,因为go语言没有类似malloc的函数且指针不能参与运算,所以用切片来模拟
type String struct {
	Data []rune
	Length int
}

//实现Stringer接口
func (s String) String() string {
	return string(s.Data)
}

// Init 初始化
func (s *String) Init() {
	s.Data=nil
	s.Length=0
}

// Assign 用string给自己模拟的字符串结构赋值
func (s *String) Assign(value string) {
	s.Data=[]rune(value)
	s.Length=len(s.Data)
}

// BF 暴力算法求子串
func (s *String) BF(sub String)(position int)  {
	subStringIndex,masterStringIndex:=0,0

	for masterStringIndex<s.Length&&subStringIndex<sub.Length{

		if sub.Data[subStringIndex]==s.Data[masterStringIndex]{
			subStringIndex++
			masterStringIndex++
		}else {
			subStringIndex=0
			masterStringIndex=masterStringIndex-subStringIndex+1
		}
	}

	if subStringIndex==sub.Length{
		//举例说明,如果主串是 abcd,子串是abc,那么返回1,而不是返回0
		return masterStringIndex-subStringIndex+1
	}else {
		return -1
	}
}

// KMP kmp算法求子串位置
func (s *String) KMP(sub String)(position int)  {
	next:=make([]int,len(sub.Data))
	sub.Next(next)
	subStringIndex,masterStringIndex:=0,0

	for masterStringIndex<s.Length&&subStringIndex<sub.Length{

		if sub.Data[subStringIndex]==s.Data[masterStringIndex]{
			subStringIndex++
			masterStringIndex++
		}else {
			subStringIndex=next[subStringIndex+1]
		}
	}

	if subStringIndex==sub.Length{
		//举例说明,如果主串是 abcd,子串是abc,那么返回1,而不是返回0
		return masterStringIndex-subStringIndex+1
	}else {
		return -1
	}
}

// Next 求KMP算法的next数组
func (s *String) Next(next []int) {
		j,i:=0,1
		next[1]=0
		for i<s.Length{
			if j==0||s.Data[i]==s.Data[j]{
				i++
				j++
				if s.Data[i]!=s.Data[j]{
					next[i]=j
				}else {
					next[i]=next[j]
				}
			}else {
				j=next[j]
			}

		}
}

posted @ 2021-11-06 17:01  读史  阅读(69)  评论(0编辑  收藏  举报