You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
3.0 KiB

5 months ago
package utils
import (
"fmt"
"math"
"math/rand"
"strconv"
"strings"
"sync"
"time"
"github.com/xrash/smetrics"
)
func GetInvitation() string {
var bs = make([]byte, 6)
for i := 0; i < 6; i++ {
rand.Seed(time.Now().UnixNano())
flag := rand.Intn(2)
if flag == 1 {
bs[i] = byte(rand.Float64()*10 + 48)
} else {
bs[i] = byte(rand.Float64()*26 + 65)
}
}
return string(bs)
}
func GetInvitationLen(length int) string {
var bs = make([]byte, length)
for i := 0; i < length; i++ {
rand.Seed(time.Now().UnixNano())
flag := rand.Intn(3)
if flag == 1 {
bs[i] = byte(rand.Float64()*10 + 48)
} else if flag == 0 {
bs[i] = byte(rand.Float64()*26 + 65)
} else {
bs[i] = byte(rand.Float64()*26 + 97)
}
}
return string(bs)
}
func StringFloat64ToInt(s string) int {
f1, err := strconv.ParseFloat(s, 64)
if err != nil {
return 0
}
s1 := strconv.FormatFloat(math.Ceil(f1), 'f', -1, 64)
i, _ := strconv.Atoi(s1)
return i
}
// FindMostSimilarCode 使用协程并发地对比目标特征码与一组候选特征码,
// 并找出相似度最高的特征码(若相似度高于阈值)及其相似度。
func FindMostSimilarCode(targetCode string, candidateCodes []string, similarityThreshold float64, boostThreshold float64, prefixSize int) (string, float64, bool) {
var wg sync.WaitGroup
maxSimilarity := 0.0
var closestCode string
foundAboveThreshold := false
resultChan := make(chan struct {
similarity float64
code string
})
for _, candidate := range candidateCodes {
wg.Add(1)
go func(candidate string) {
defer wg.Done()
similarity := smetrics.JaroWinkler(targetCode, candidate, boostThreshold, prefixSize)
resultChan <- struct {
similarity float64
code string
}{similarity, candidate}
}(candidate)
}
go func() {
wg.Wait()
close(resultChan)
}()
for result := range resultChan {
if result.similarity > maxSimilarity {
maxSimilarity = result.similarity
closestCode = result.code
if maxSimilarity >= similarityThreshold {
foundAboveThreshold = true
}
}
}
return closestCode, maxSimilarity, foundAboveThreshold
}
// 计算余弦相似度
func CosineSimilarity(vec1Str, vec2Str string) float64 {
vec1, _ := parseVectorFromString(vec1Str)
vec2, _ := parseVectorFromString(vec2Str)
dotProduct := 0.0
vec1Norm := 0.0
vec2Norm := 0.0
for i := range vec1 {
dotProduct += vec1[i] * vec2[i]
vec1Norm += vec1[i] * vec1[i]
vec2Norm += vec2[i] * vec2[i]
}
if vec1Norm == 0 || vec2Norm == 0 {
return 0
}
return dotProduct / (math.Sqrt(vec1Norm) * math.Sqrt(vec2Norm))
}
func parseVectorFromString(vecStr string) ([]float64, error) {
vec := strings.Split(vecStr, ",")
var parsedVec []float64
for _, strVal := range vec {
floatVal, err := strconv.ParseFloat(strVal, 64)
if err != nil {
return nil, fmt.Errorf("failed to parse float value '%s': %w", strVal, err)
}
parsedVec = append(parsedVec, floatVal)
}
return parsedVec, nil
}
// float64转string的函数
func Float64ToString(input float64) string {
return strconv.FormatFloat(input, 'f', -1, 64)
}