-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwubi.go
173 lines (149 loc) · 3.54 KB
/
wubi.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
package wubi
import (
"errors"
"sort"
"strings"
"github.com/gopherlib/wubi/dict"
)
// Dictionary 五笔码表
type Dictionary map[string]string
// Version 五笔版本
type Version string
// 默认支持的版本
const (
Version86 Version = "86"
Version98 Version = "98"
Version06 Version = "06"
)
var (
dictList = map[Version]Dictionary{
Version86: dict.Dict86,
Version98: dict.Dict98,
Version06: dict.Dict06,
}
)
// RegisterVersion 注册自定义版本,可以覆盖默认的码表数据
func RegisterVersion(ver Version, dict Dictionary) {
dictList[ver] = dict
}
// New86 86版
func New86() *Wubi {
return &Wubi{
dictChar2Code: dict.Dict86,
dictCode2Char: reverseDict(dict.Dict86),
}
}
// New98 98版
func New98() *Wubi {
return &Wubi{
dictChar2Code: dict.Dict98,
dictCode2Char: reverseDict(dict.Dict98),
}
}
// New06 新世纪版
func New06() *Wubi {
return &Wubi{
dictChar2Code: dict.Dict06,
dictCode2Char: reverseDict(dict.Dict06),
}
}
// New 创建一个转换器实例
func New(ver Version) (*Wubi, error) {
if d, ok := dictList[ver]; ok {
return &Wubi{
dictChar2Code: d,
dictCode2Char: reverseDict(d),
}, nil
}
return nil, errors.New("invalid version")
}
// NenWithDict 使用自定义码表创建转换器实例
func NenWithDict(d Dictionary) *Wubi {
return &Wubi{
dictChar2Code: d,
dictCode2Char: reverseDict(d),
}
}
// Wubi 五笔码转换器
type Wubi struct {
dictChar2Code Dictionary
dictCode2Char Dictionary
}
// GetCode 获取单字的五笔码
func (c Wubi) GetCode(char rune) []string {
if code, ok := c.dictChar2Code[string(char)]; ok {
codes := strings.Split(code, ",")
c.sort(codes)
return codes
}
return nil
}
// GetCodes 获取字符串的五笔码列表
func (c Wubi) GetCodes(chars string) [][]string {
codes := make([][]string, 0, len(chars))
for _, r := range []rune(chars) {
code := c.GetCode(r)
if len(code) == 0 {
// 如果字符没有对应的五笔码,则原样返回
codes = append(codes, []string{string(r)})
} else {
// 对五笔码进行排序,简码在前,全码在后
if len(code) > 0 {
c.sort(code)
}
codes = append(codes, code)
}
}
return codes
}
// GetChar 获取单个五笔码对应的汉字
func (c Wubi) GetChar(code string) []string {
if char, ok := c.dictCode2Char[code]; ok {
chars := strings.Split(char, ",")
sort.Sort(sort.StringSlice(chars))
return chars
}
return nil
}
// GetChars 获取五笔码列表对应的汉字
func (c Wubi) GetChars(codes []string) [][]string {
chars := make([][]string, 0, len(codes))
for _, code := range codes {
cs := c.GetChar(code)
if len(cs) == 0 {
// 如果五笔码没有对应的汉字,则原样返回
chars = append(chars, []string{code})
} else {
if len(cs) > 0 {
sort.Sort(sort.StringSlice(cs))
}
chars = append(chars, cs)
}
}
return chars
}
func (c Wubi) sort(codes []string) {
sort.Sort(codeSlice(codes))
}
// reverseDict 翻转字典
func reverseDict(dict Dictionary) Dictionary {
newArrDict := make(map[string][]string, len(dict))
newDict := make(Dictionary, len(dict))
// key,val 原始字典中的 key => val
for key, val := range dict {
// 原始字典的val是以 , 分隔的数组字符串, 这里还原为数组格式
vals := strings.Split(val, ",")
for _, v := range vals {
// 对每个val进行反转
if _, ok := newArrDict[v]; ok {
newArrDict[v] = append(newArrDict[v], key)
} else {
newArrDict[v] = []string{key}
}
}
}
for key, vals := range newArrDict {
newDict[key] = strings.Join(vals, ",")
}
return newDict
}