98 lines
2.1 KiB
Go
98 lines
2.1 KiB
Go
package quesbank
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
)
|
|
|
|
// ParseAIAnswer 解析AI答案
|
|
func ParseAIAnswer(aiResponse string) ([]string, error) {
|
|
aiResponse = strings.TrimSpace(aiResponse)
|
|
|
|
// 尝试直接解析JSON数组
|
|
var answers []string
|
|
if err := json.Unmarshal([]byte(aiResponse), &answers); err == nil {
|
|
return answers, nil
|
|
}
|
|
|
|
// 尝试从响应中提取JSON数组
|
|
start := strings.Index(aiResponse, "[")
|
|
end := strings.LastIndex(aiResponse, "]")
|
|
if start != -1 && end != -1 && end > start {
|
|
jsonStr := aiResponse[start : end+1]
|
|
if err := json.Unmarshal([]byte(jsonStr), &answers); err == nil {
|
|
return answers, nil
|
|
}
|
|
}
|
|
|
|
// 如果都失败,返回原始响应作为单个答案
|
|
return []string{aiResponse}, nil
|
|
}
|
|
|
|
// MatchAnswerToOption 将AI答案匹配到选项
|
|
func MatchAnswerToOption(answer string, options map[string]string) string {
|
|
// 精确匹配
|
|
for key, val := range options {
|
|
if val == answer || strings.TrimSpace(val) == strings.TrimSpace(answer) {
|
|
return key
|
|
}
|
|
}
|
|
|
|
// 模糊匹配(包含关系)
|
|
for key, val := range options {
|
|
if strings.Contains(val, answer) || strings.Contains(answer, val) {
|
|
return key
|
|
}
|
|
}
|
|
|
|
// 相似度匹配
|
|
bestKey := ""
|
|
bestScore := 0.0
|
|
for key, val := range options {
|
|
score := similarity(answer, val)
|
|
if score > bestScore {
|
|
bestScore = score
|
|
bestKey = key
|
|
}
|
|
}
|
|
if bestScore >= 0.5 {
|
|
return bestKey
|
|
}
|
|
|
|
return ""
|
|
}
|
|
|
|
// similarity 计算字符串相似度(简单实现)
|
|
func similarity(s1, s2 string) float64 {
|
|
if s1 == s2 {
|
|
return 1.0
|
|
}
|
|
if len(s1) == 0 || len(s2) == 0 {
|
|
return 0.0
|
|
}
|
|
|
|
// 使用最长公共子序列计算相似度
|
|
lcs := longestCommonSubsequence(s1, s2)
|
|
return float64(lcs) / float64(max(len(s1), len(s2)))
|
|
}
|
|
|
|
// longestCommonSubsequence 计算最长公共子序列长度
|
|
func longestCommonSubsequence(s1, s2 string) int {
|
|
m, n := len(s1), len(s2)
|
|
dp := make([][]int, m+1)
|
|
for i := range dp {
|
|
dp[i] = make([]int, n+1)
|
|
}
|
|
|
|
for i := 1; i <= m; i++ {
|
|
for j := 1; j <= n; j++ {
|
|
if s1[i-1] == s2[j-1] {
|
|
dp[i][j] = dp[i-1][j-1] + 1
|
|
} else {
|
|
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
|
|
}
|
|
}
|
|
}
|
|
return dp[m][n]
|
|
}
|