golang字符串比较与编辑距离算法插件库go-edlib的使用
Golang字符串比较与编辑距离算法插件库go-edlib的使用
介绍
Go-edlib是一个Golang开源库,包含了多种编辑距离和字符串比较算法,并支持Unicode字符。该库具有100%的测试覆盖率。
功能特性
- Levenshtein距离
- LCS(最长公共子序列)及其编辑距离、回溯和差异功能
- Hamming距离
- Damerau-Levenshtein距离(包含OSA和相邻转置算法)
- Jaro & Jaro-Winkler相似度算法
- 余弦相似度
- Jaccard指数
- QGram
- Sorensen-Dice系数
- 基于所有可用编辑距离算法的相似度百分比计算
- 基于编辑距离的模糊搜索功能(支持单结果和多结果输出)
- Unicode兼容
安装
在项目目录下运行:
go get github.com/hbollon/go-edlib
然后在代码中导入:
import (
"github.com/hbollon/go-edlib"
)
使用示例
1. 计算两个字符串的相似度
res, err := edlib.StringsSimilarity("string1", "string2", edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Similarity: %f", res)
}
2. 执行模糊搜索
2.1 无阈值的最匹配结果
strList := []string{"test", "tester", "tests", "testers", "testing", "tsting", "sting"}
res, err := edlib.FuzzySearch("testnig", strList, edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Result: %s", res)
}
2.2 带阈值的最匹配结果
strList := []string{"test", "tester", "tests", "testers", "testing", "tsting", "sting"}
res, err := edlib.FuzzySearchThreshold("testnig", strList, 0.7, edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Result: %s", res)
}
3. 获取原始编辑距离
res := edlib.LevenshteinDistance("kitten", "sitting")
fmt.Printf("Result: %d", res)
4. LCS相关操作
4.1 计算LCS长度
lcs := edlib.LCS("ABCD", "ACBAD")
fmt.Printf("Length of their LCS: %d", lcs)
4.2 回溯LCS
res, err := edlib.LCSBacktrack("ABCD", "ACBAD")
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("LCS: %s", res)
}
4.3 获取LCS差异
res, err := edlib.LCSDiff("computer", "houseboat")
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("LCS Diff: \n%s\n%s", res[0], res[1])
}
完整示例
package main
import (
"fmt"
"github.com/hbollon/go-edlib"
"strings"
)
func main() {
// 1. 字符串相似度计算
similarity, err := edlib.StringsSimilarity("hello", "hallo", edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Similarity between 'hello' and 'hallo': %.2f\n", similarity)
}
// 2. 模糊搜索
strList := []string{"test", "tester", "tests", "testers", "testing", "tsting", "sting"}
// 2.1 无阈值搜索
result, err := edlib.FuzzySearch("testnig", strList, edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Fuzzy search result for 'testnig': %s\n", result)
}
// 2.2 带阈值搜索
result, err = edlib.FuzzySearchThreshold("testnig", strList, 0.7, edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Fuzzy search with threshold 0.7: %s\n", result)
}
// 3. 编辑距离计算
levDist := edlib.LevenshteinDistance("kitten", "sitting")
fmt.Printf("Levenshtein distance between 'kitten' and 'sitting': %d\n", levDist)
// 4. LCS操作
// 4.1 LCS长度
lcsLen := edlib.LCS("ABCD", "ACBAD")
fmt.Printf("LCS length between 'ABCD' and 'ACBAD': %d\n", lcsLen)
// 4.2 LCS回溯
lcs, err := edlib.LCSBacktrack("ABCD", "ACBAD")
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("LCS between 'ABCD' and 'ACBAD': %s\n", lcs)
}
// 4.3 LCS差异
diff, err := edlib.LCSDiff("computer", "houseboat")
if err != nil {
fmt.Println(err)
} else {
fmt.Println("LCS Diff between 'computer' and 'houseboat':")
fmt.Println(diff[0])
fmt.Println(diff[1])
}
// 5. 多结果模糊搜索
results, err := edlib.FuzzySearchSet("testnig", strList, 3, edlib.Levenshtein)
if err != nil {
fmt.Println(err)
} else {
fmt.Printf("Top 3 matches for 'testnig': %s\n", strings.Join(results, ", "))
}
}
作者
👤 Hugo Bollon
许可证
该项目采用MIT许可证授权。
更多关于golang字符串比较与编辑距离算法插件库go-edlib的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang字符串比较与编辑距离算法插件库go-edlib的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go语言字符串比较与编辑距离算法:go-edlib库使用指南
字符串比较基础
在Go语言中,最基本的字符串比较方式是使用==
运算符或strings.Compare()
函数:
package main
import (
"fmt"
"strings"
)
func main() {
str1 := "hello"
str2 := "world"
str3 := "hello"
// 使用==比较
fmt.Println(str1 == str2) // false
fmt.Println(str1 == str3) // true
// 使用strings.Compare
fmt.Println(strings.Compare(str1, str2)) // -1 (str1 < str2)
fmt.Println(strings.Compare(str1, str3)) // 0 (相等)
}
go-edlib库介绍
go-edlib是一个强大的字符串比较和模糊匹配库,提供了多种字符串相似度算法:
- Levenshtein距离(编辑距离)
- Damerau-Levenshtein距离
- Jaro-Winkler相似度
- 余弦相似度
- Jaccard相似度
- Sorensen-Dice相似度
- 汉明距离
安装go-edlib
go get github.com/hbollon/go-edlib
基本使用示例
1. 计算字符串相似度
package main
import (
"fmt"
"github.com/hbollon/go-edlib"
)
func main() {
str1 := "kitten"
str2 := "sitting"
// 计算Levenshtein距离
levDist, err := goedlib.LevenshteinDistance(str1, str2)
if err != nil {
panic(err)
}
fmt.Printf("Levenshtein距离: %d\n", levDist) // 3
// 计算相似度(0-1)
similarity, err := goedlib.StringSimilarity(str1, str2, goedlib.Levenshtein)
if err != nil {
panic(err)
}
fmt.Printf("相似度: %.2f\n", similarity) // 0.57
}
2. 使用不同算法比较
func compareWithDifferentAlgorithms() {
str1 := "apple"
str2 := "appel"
// Jaro-Winkler相似度
jw, _ := goedlib.StringSimilarity(str1, str2, goedlib.JaroWinkler)
fmt.Printf("Jaro-Winkler: %.2f\n", jw) // 0.96
// 余弦相似度
cos, _ := goedlib.StringSimilarity(str1, str2, goedlib.Cosine)
fmt.Printf("余弦相似度: %.2f\n", cos) // 0.80
// Jaccard相似度
jac, _ := goedlib.StringSimilarity(str1, str2, goedlib.Jaccard)
fmt.Printf("Jaccard: %.2f\n", jac) // 0.67
}
3. 字符串模糊搜索
func fuzzySearchExample() {
strList := []string{"hello", "world", "golang", "good", "hallo", "hell"}
target := "hello"
// 查找最相似的字符串
result, err := goedlib.FuzzySearch(target, strList, goedlib.Levenshtein)
if err != nil {
panic(err)
}
fmt.Printf("最相似的字符串: %s\n", result) // hello
// 查找相似度大于阈值的所有字符串
matches, err := goedlib.FuzzySearchThreshold(target, strList, 0.6, goedlib.JaroWinkler)
if err != nil {
panic(err)
}
fmt.Printf("相似度>0.6的字符串: %v\n", matches) // [hello hallo hell]
}
4. 字符串差异高亮
func diffHighlightExample() {
str1 := "kitten"
str2 := "sitting"
diff := goedlib.Diff(str1, str2, goedlib.Levenshtein)
fmt.Println("差异高亮:")
fmt.Println(diff[0]) // k(i)t(t)e(n)
fmt.Println(diff[1]) // s(i)t(t)i(n)g)
}
性能考虑
不同算法的性能特点:
- Levenshtein/Damerau-Levenshtein: 精确但较慢,O(n*m)时间复杂度
- Jaro-Winkler: 较快,适合短字符串
- Cosine/Jaccard: 适合基于词或n-gram的比较
对于大数据集,可以考虑先使用快速算法(如Jaro-Winkler)筛选,再对候选结果使用更精确的算法。
实际应用场景
- 拼写检查与纠正:
func suggestCorrection(input string, dictionary []string) string {
result, _ := goedlib.FuzzySearch(input, dictionary, goedlib.JaroWinkler)
return result
}
- 数据清洗:
func deduplicateSimilar(list []string, threshold float64) []string {
var result []string
for _, s1 := range list {
found := false
for _, s2 := range result {
sim, _ := goedlib.StringSimilarity(s1, s2, goedlib.Levenshtein)
if sim > threshold {
found = true
break
}
}
if !found {
result = append(result, s1)
}
}
return result
}
- 搜索建议:
func getSearchSuggestions(query string, options []string) []string {
var suggestions []string
for _, opt := range options {
sim, _ := goedlib.StringSimilarity(query, opt, goedlib.Cosine)
if sim > 0.7 {
suggestions = append(suggestions, opt)
}
}
return suggestions
}
总结
go-edlib提供了丰富的字符串比较算法,可以满足从精确匹配到模糊搜索的各种需求。根据具体场景选择合适的算法:
- 需要精确编辑距离时:Levenshtein/Damerau-Levenshtein
- 快速模糊匹配:Jaro-Winkler
- 基于词或n-gram的比较:Cosine/Jaccard
- 短字符串比较:Hamming
通过合理使用这些算法,可以显著提升应用程序处理自然语言和用户输入的灵活性和用户体验。