diff --git a/readme.md b/readme.md index 2edc6cf..206a8be 100644 --- a/readme.md +++ b/readme.md @@ -77,6 +77,8 @@ 2021/03/11: 新增Kr、Shift and/or字符串匹配算法 +2021/03/14: 新增Manacher算法,求最长回文串 + # 修复日志 2020/11/23:修改项目案例(按照一定规则对一组数据进行排序分组) diff --git a/util/palindrome/Manacher.go b/util/palindrome/Manacher.go new file mode 100644 index 0000000..f0b851d --- /dev/null +++ b/util/palindrome/Manacher.go @@ -0,0 +1,55 @@ +/* + * @Author : huangzj + * @Time : 2021/3/13 21:58 + * @Description: + */ + +package palindrome + +import "fmt" + +//返回字符串中最大回文的数量和回文字符串 +func Manacher(allString string) (int, string) { + maxMid := 0 //当前最大回文串中部下标 + radiusPos := 0 //最大回文半径对应的右边的下标位置 + result := generateString(allString) + point := make([]int, len(result)) //以j为中心的最长回文半径 + maxLen := -1 + var palindrome string + + for i := 1; i < len(result); i++ { + j := 2*maxMid - i //与i下标对称的左边的下标 + if i >= radiusPos { + point[i] = 1 + } else if radiusPos-i > point[j] { + point[i] = point[j] + } else { + // point[j] >= radiusPos-i + point[i] = radiusPos - i + } + //从后面的位置继续开始找对应的字符 + for (i-point[i] >= 0 && i+point[i] < len(result)) && result[i+point[i]] == result[i-point[i]] { + point[i]++ + } + //更新最长回文串信息 + if i+point[i] > radiusPos { + maxMid = i + radiusPos = i + point[i] + } + if maxLen < point[i]-1 && point[i]-1 > 1 { + maxLen = point[i] - 1 + palindrome = allString[maxMid/2-maxLen/2 : radiusPos/2] + } + } + + return maxLen, palindrome +} + +//把字符串转换成特殊的字符串 +func generateString(allString string) string { + var result string + for i := range allString { + result = fmt.Sprintf("%s%s%c", result, "#", allString[i]) + } + return fmt.Sprintf("%s%s", result, "#") +} diff --git a/util/palindrome/Manacher_test.go b/util/palindrome/Manacher_test.go new file mode 100644 index 0000000..074fa61 --- /dev/null +++ b/util/palindrome/Manacher_test.go @@ -0,0 +1,28 @@ +/* + * @Author : huangzj + * @Time : 2021/3/13 21:58 + * @Description: + */ + +package palindrome + +import ( + "fmt" + "testing" +) + +func TestGenerateString(t *testing.T) { + fmt.Println(generateString("abcdef")) + fmt.Println(generateString("abc2342def")) + fmt.Println(generateString("abcdef3213")) + fmt.Println(generateString("abcderewrewr312f")) + fmt.Println(generateString("312312abcdef321e")) +} + +func TestPalindrome(t *testing.T) { + fmt.Println(Manacher("abcabccbacba")) + fmt.Println(Manacher("mabcabccbacbammm")) + fmt.Println(Manacher("habcabccbacbammm")) + fmt.Println(Manacher("hmmmabcabccbacbammm")) + fmt.Println(Manacher("abcdefghij")) +}