mirror of
https://github.com/fumiama/emozi.git
synced 2026-07-02 01:40:22 +08:00
feat(coder): finish decode
This commit is contained in:
149
lookup.go
149
lookup.go
@@ -3,44 +3,35 @@ package emozi
|
||||
import (
|
||||
"math/rand"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var 空 = "🈳️"
|
||||
|
||||
func (c *Coder) 查声母(s 声母枚举) string {
|
||||
lst := 声母[s]
|
||||
func 随机正查(m [][]string, isRandom bool, i uint8) string {
|
||||
lst := m[i]
|
||||
if len(lst) == 0 {
|
||||
return 空
|
||||
}
|
||||
if len(lst) == 1 || !c.isRandom {
|
||||
if len(lst) == 1 || !isRandom {
|
||||
return lst[0]
|
||||
}
|
||||
return lst[rand.Intn(len(lst))]
|
||||
}
|
||||
|
||||
func (c *Coder) 查韵母(y 韵母枚举) string {
|
||||
lst := 韵母[y]
|
||||
if len(lst) == 0 {
|
||||
return 空
|
||||
}
|
||||
if len(lst) == 1 || !c.isRandom {
|
||||
return lst[0]
|
||||
}
|
||||
return lst[rand.Intn(len(lst))]
|
||||
func (c *Coder) 声母(isRandom bool, s 声母枚举) string {
|
||||
return 随机正查(声母[:], isRandom, uint8(s))
|
||||
}
|
||||
|
||||
func (c *Coder) 查声调(t 声调枚举) string {
|
||||
lst := 声调[t]
|
||||
if len(lst) == 0 {
|
||||
return 空
|
||||
}
|
||||
if len(lst) == 1 || !c.isRandom {
|
||||
return lst[0]
|
||||
}
|
||||
return lst[rand.Intn(len(lst))]
|
||||
func (c *Coder) 韵母(isRandom bool, y 韵母枚举) string {
|
||||
return 随机正查(韵母[:], isRandom, uint8(y))
|
||||
}
|
||||
|
||||
func (c *Coder) 查部首(r rune) string {
|
||||
func (c *Coder) 声调(isRandom bool, t 声调枚举) string {
|
||||
return 随机正查(声调[:], isRandom, uint8(t))
|
||||
}
|
||||
|
||||
func (c *Coder) 部首(r rune) string {
|
||||
c.mu.RLock()
|
||||
e, ok := c.部首缓存[r]
|
||||
c.mu.RUnlock()
|
||||
@@ -62,3 +53,117 @@ func (c *Coder) 查部首(r rune) string {
|
||||
c.部首缓存[r] = 空
|
||||
return 空
|
||||
}
|
||||
|
||||
func 二阶逆查[E ~uint8](lowm map[rune][]string, m map[string]E, s string) (enum E, n int) {
|
||||
lowk := rune(0)
|
||||
lows := s
|
||||
if len(lows) > 12 {
|
||||
lows = lows[:12]
|
||||
}
|
||||
r := []rune(lows)
|
||||
if len(r) == 0 {
|
||||
return
|
||||
}
|
||||
lowk = r[0]
|
||||
ks := lowm[lowk]
|
||||
if len(ks) == 0 {
|
||||
return
|
||||
}
|
||||
// 寻找最长匹配 T
|
||||
matchp := -1
|
||||
matchl := 0
|
||||
for i, k := range ks {
|
||||
if strings.HasPrefix(s, k) {
|
||||
if len(k) > matchl {
|
||||
matchl = len(k)
|
||||
matchp = i
|
||||
}
|
||||
}
|
||||
}
|
||||
if matchp < 0 {
|
||||
return
|
||||
}
|
||||
enum, ok := m[ks[matchp]]
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
n = matchl
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Coder) 逆声母(s string) (声母枚举, int) {
|
||||
return 二阶逆查[声母枚举](低阶逆声母, 逆声母, s)
|
||||
}
|
||||
|
||||
func (c *Coder) 逆韵母(s string) (韵母枚举, int) {
|
||||
return 二阶逆查[韵母枚举](低阶逆韵母, 逆韵母, s)
|
||||
}
|
||||
func (c *Coder) 逆声调(s string) (声调枚举, int) {
|
||||
return 二阶逆查[声调枚举](低阶逆声调, 逆声调, s)
|
||||
}
|
||||
|
||||
func (c *Coder) 逆部首(s string) (rs []rune, n int) {
|
||||
lim := len(s)
|
||||
if lim > 32 {
|
||||
lim = 32
|
||||
}
|
||||
c.mu.RLock()
|
||||
for i := 1; i < lim; i++ {
|
||||
l := c.逆部首缓存[s[:i]]
|
||||
if len(l) > 0 {
|
||||
rs = l
|
||||
n = i
|
||||
}
|
||||
}
|
||||
c.mu.RUnlock()
|
||||
if n > 0 && len(rs) > 0 {
|
||||
return
|
||||
}
|
||||
x := &部首表{}
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("WHERE ")
|
||||
for i := 1; i < lim; i++ {
|
||||
sb.WriteString("E='")
|
||||
sb.WriteString(s[:i])
|
||||
sb.WriteString("' OR ")
|
||||
}
|
||||
q := sb.String()[:sb.Len()-4]
|
||||
n = 0
|
||||
e := ""
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
err := c.db.FindFor(部首表名, x, q, func() error {
|
||||
if len(x.E) > n {
|
||||
n = len(x.E)
|
||||
rs = rs[:0]
|
||||
e = x.E
|
||||
}
|
||||
if len(x.E) == n && 无此字符(rs, x.R) {
|
||||
rs = append(rs, x.R)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err == nil && len(rs) > 0 && n > 0 {
|
||||
c.逆部首缓存[e] = rs
|
||||
return
|
||||
}
|
||||
for i := 1; i < lim; i++ {
|
||||
k := s[:i]
|
||||
innerrs, ok := 逆部首后备[k]
|
||||
c.逆部首缓存[k] = innerrs
|
||||
if ok && len(innerrs) > 0 {
|
||||
n = i
|
||||
rs = innerrs
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func 无此字符(runes []rune, ch rune) bool {
|
||||
for _, r := range runes {
|
||||
if ch == r {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user