1. 程式人生 > 其它 >資料結構go語言實現(2)字串與kmp演算法

資料結構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]
			}

		}
}