golang实现字符串匹配算法BF,KMP,Sunday,BM


func printSubStr(i, j int, s, temp string) {
	str := s[i:]
	if i+j < len(s) {
		str = s[i : i+j+1]
	}
	fmt.Print(i, i+j, str, temp)
}

func BF(s, temp string) bool {
	for i := range s {
		for j := range temp {
			if i+j == len(s) {
				return false
			}
			if s[i+j] != temp[j] {
				break
			}
			if j == len(temp)-1 {
				printSubStr(i, j, s, temp)
				return true
			}
		}
	}
	return false
}

func KMP(s, temp string) bool {
	iArr := make([]int, 0, len(s))
	for i, v := range s {
		if i == 0 {
			iArr = append(iArr, 0)
			continue
		}
		if uint8(v) == s[iArr[i-1]] {
			iArr = append(iArr, 1+iArr[i-1])
		} else {
			iArr = append(iArr, 0)
		}
	}

	for i := 0; i < len(s); i++ {
		for j := range temp {
			if i+j == len(s) {
				return false
			}
			if s[i+j] != temp[j] {
				if j == 0 {
					break
				}
				i += len(temp) - iArr[j-1]
				break
			}
			if j == len(temp)-1 {
				printSubStr(i, j, s, temp)
				return true
			}
		}
	}
	return false
}

func Sunday(s, temp string) bool {
	var tempIndex = make(map[uint8]int)
	for i := range temp {
		tempIndex[temp[i]] = i
	}
	for i := 0; i < len(s); {
		if i+len(temp) > len(s) {
			return false
		}
		for j, _ := range temp {
			if s[i+j] != temp[j] {
				if i+len(temp) == len(s) {
					return false
				}
				if _, ok := tempIndex[s[i+len(temp)]]; !ok {
					i = len(temp) + i + 1
					break
				} else {
					i += len(temp) - tempIndex[s[i+len(temp)]]
					break
				}
			}
			if j == len(temp)-1 {
				printSubStr(i, j, s, temp)
				return true
			}
		}
	}
	return true
}

// 算法写的有点麻烦,觉得不好请指导
func BM(s, temp string) (bool, int) {
	if s == temp {
		return true, 0
	}
	if temp == "" {
		return false, 0
	}
	var goodChar = make(map[uint8]struct{})
	var goodSuffix = make(map[int]int)
	if len(temp) == 1 {
		goodSuffix[0] = -1
		goodChar[temp[0]] = struct{}{}
	} else {
		for i := len(temp) - 1; i > -1; i-- {
			goodChar[temp[i]] = struct{}{}
			if i >= len(temp)/2 {
				if ok, index := BM(temp, temp[i:]); ok && index != i { // 计算好后缀所在位置
					goodSuffix[i] = index
				} else {
					goodSuffix[i] = -1
				}
			} else {
				goodSuffix[i] = -1
			}
		}
	}
	var tmpIndex int
	for i := 0; i < len(s)-len(temp); {
		tmpIndex = i + len(temp)
		goodSuffixIndex := -1
		for j := len(temp) - 1; j >= 0; j-- {
			if goodSuffix[j] >= 0 { // 取到最左好后缀
				goodSuffixIndex = goodSuffix[j]
			}
			if s[tmpIndex] != temp[j] {
				if _, ok := goodChar[s[tmpIndex]]; !ok { // 判断是否是坏字符
					i += len(temp)
					break
				}
				i += j - goodSuffixIndex
				break
			}
			if j == 0 {
				printSubStr(tmpIndex, len(temp)-1, s, temp)
				return true, i
			}
			tmpIndex--
		}

	}
	return false, 0
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值