| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- package utils
- import (
- "math"
- )
- // LevenshteinDistance 计算两个字符串的编辑距离
- func LevenshteinDistance(s1, s2 string) int {
- r1, r2 := []rune(s1), []rune(s2)
- rows := len(r1) + 1
- cols := len(r2) + 1
- d := make([][]int, rows)
- for i := range d {
- d[i] = make([]int, cols)
- }
- for i := 1; i < rows; i++ {
- d[i][0] = i
- }
- for j := 1; j < cols; j++ {
- d[0][j] = j
- }
- for i := 1; i < rows; i++ {
- for j := 1; j < cols; j++ {
- cost := 0
- if r1[i-1] != r2[j-1] {
- cost = 1
- }
- d[i][j] = min(
- min(d[i-1][j]+1, d[i][j-1]+1),
- d[i-1][j-1]+cost,
- )
- }
- }
- return d[rows-1][cols-1]
- }
- // StringSimilarity 计算字符串相似度 (0-1之间,1表示完全相同)
- func StringSimilarity(s1, s2 string) float64 {
- if s1 == s2 {
- return 1.0
- }
- maxLen := math.Max(float64(len([]rune(s1))), float64(len([]rune(s2))))
- if maxLen == 0 {
- return 1.0
- }
- distance := LevenshteinDistance(s1, s2)
- return 1.0 - float64(distance)/maxLen
- }
- // FindBestMatch 在多个候选项中找到与目标字符串最相似的匹配
- func FindBestMatch(target string, candidates []string) (string, float64) {
- if len(candidates) == 0 {
- return "", 0.0
- }
- bestMatch := candidates[0]
- bestScore := StringSimilarity(target, candidates[0])
- for i := 1; i < len(candidates); i++ {
- score := StringSimilarity(target, candidates[i])
- if score > bestScore {
- bestScore = score
- bestMatch = candidates[i]
- }
- }
- return bestMatch, bestScore
- }
- // MatchResult 匹配结果结构体
- type MatchResult struct {
- Text string `json:"text"`
- Score float64 `json:"score"`
- }
- // FindBestMatches 返回所有候选项的相似度分数,按分数降序排列
- func FindBestMatches(target string, candidates []string) []MatchResult {
- results := make([]MatchResult, len(candidates))
- for i, candidate := range candidates {
- score := StringSimilarity(target, candidate)
- results[i] = MatchResult{
- Text: candidate,
- Score: score,
- }
- }
- // 按分数降序排序
- for i := 0; i < len(results)-1; i++ {
- for j := i + 1; j < len(results); j++ {
- if results[i].Score < results[j].Score {
- results[i], results[j] = results[j], results[i]
- }
- }
- }
- return results
- }
- // min 辅助函数
- func min(a, b int) int {
- if a < b {
- return a
- }
- return b
- }
|