算法:五笔编码,如何根据输入的词条自动生成输入编码
一、想要实现的
最近做的一个五笔码表工具,想要实现根据用户输入的词条自动生成输入编码。
比如:
输入 我们
生成 trwu
输入 五笔基础知识
生成 gtay
二、五笔基础知识
五笔的所有输入编码都最多只有4个字母,规则是这样的:
- 一个字时,字的前三个编码对应字母,和最后一个编码应用字母
- 两个字时,取这两个字的前两个字根字母
- 三个字时,取前两个字的第一个字根,第三个字的前两个字根
- 四个或更多字时,取前三个字的第一个字根,最后一个字的第一个字根
我要处理的五笔码表是这样的:
前面是词条,后面是词条对应的输入码
工兵 aarg
戒掉 aarh
芭蕾舞 aarl
熙熙攘攘 aarr
芽接 aaru
戒指 aarx
工模 aasa
工棚 aase
工本 aasg
花草树木 aass
式样 aasu
荛 aat
三、如何实现
1. 获取字典
先从基础码表中筛选出一套单字字典来,满足以下几个条件:
- 单字
- 编码在2个以上(因为2字以上的词条,只需要前两个编码就能凑够五笔的4码)
我是这样实现的:
let characterMap = new Map() // 新建一个字典
this.dictMain.wordsOrigin.forEach(item => {
if (item.word.length === 1
&& item.code.length >= 2
&& !characterMap.has(item.word)) // map里不存在这个字
{ // 编码长度为 4 的单字
characterMap.set(item.word, item.code)
}
})
2. 获取每个字的编码数组
let decodeArray = [] // 每个字解码后的数组表
word.split('').forEach(ch => {
// 查询每个字的编码,并放到数组中
decodeArray.push(this.dictMain.characterMap.get(ch))
})
我们的日子
得出的数组是这样
["trn", "wu", "rqy", "jjjj", "bb"]
3. 拼成输入码
获取到了输入编码的数组,如果字数大于4,只截取4个,前三个字的编码和最后一个字的编码。
只需要根据规则将它拼起来就好了。
let decodeArray = [] // 每个字解码后的数组表
let letterArray = word.split('')
if (letterArray.length > 4){ // 只截取前三和后一
letterArray.splice(3,letterArray.length - 4)
}
letterArray.forEach(ch => {
decodeArray.push(this.dictMain.characterMap.get(ch) || '')
})
let phraseCode = ''
switch (decodeArray.length){
case 0:
case 1:
break
case 2: // 取一的前二码,二的前二码
phraseCode =
decodeArray[0].substring(0,2) +
decodeArray[1].substring(0,2)
break
case 3: // 取一二前一码,三前二码
phraseCode =
decodeArray[0].substring(0,1) +
decodeArray[1].substring(0,1) +
decodeArray[2].substring(0,2)
break
default: // 取一二三前一码,最后的一码
phraseCode =
decodeArray[0].substring(0,1) +
decodeArray[1].substring(0,1) +
decodeArray[2].substring(0,1) +
decodeArray[decodeArray.length - 1].substring(0,1)
}
console.log(phraseCode, decodeArray)
return phraseCode
最终的结果是这样: