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 }