-
Notifications
You must be signed in to change notification settings - Fork 2
/
utils.go
84 lines (76 loc) · 1.58 KB
/
utils.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package mcla
import (
"strings"
)
func rsplit(line string, b byte) (left, right string) {
i := strings.LastIndexByte(line, b)
if i < 0 {
return "", line
}
return line[:i], line[i+1:]
}
func split(line string, b byte) (left, right string) {
i := strings.IndexByte(line, b)
if i < 0 {
return line, ""
}
return line[:i], line[i+1:]
}
func lcsSplit[T comparable](a, b []T) (n int, a1, a2, b1, b2 []T) {
if len(a) == 0 || len(b) == 0 {
return 0, a, nil, b, nil
}
type ele struct {
a, b int
len int
}
ch := make([]ele, len(b)+1)
for i, p := range a {
var last ele
for j, q := range b {
cur := ch[j+1]
if p == q {
if last.len == 0 {
last = ele{i, j, 1}
} else if last.a+last.len == i && last.b+last.len == j {
last.len++
}
ch[j+1] = last
} else if prev := ch[j]; prev.len > cur.len {
ch[j+1] = prev
}
last = cur
}
}
res := ch[len(b)]
if res.len == 0 {
return
}
return res.len, a[:res.a], a[res.a+res.len:], b[:res.b], b[res.b+res.len:]
}
func lcsLength[T comparable](a, b []T) (n int) {
if len(a) == 0 || len(b) == 0 {
return 0
}
n, a1, a2, b1, b2 := lcsSplit(a, b)
n += lcsLength(a1, b1) + lcsLength(a2, b2)
return
}
func lcsPercent[T comparable](a, b []T) (v float32) {
if len(b) > len(a) {
a, b = b, a
}
if len(b) == 0 {
return 0.0
}
n := (float32)(lcsLength(a, b))
return n / (float32)(len(a))
}
func lineMatchPercent(text, match string) float32 {
if prefix, ok := strings.CutSuffix(match, " *"); ok {
if strings.HasPrefix(text, prefix) {
return 1.0
}
}
return lcsPercent(([]rune)(text), ([]rune)(match))
}