Rust 实现新世纪五笔反查词库

背景

新世纪版五笔字型输入法,简称新世纪五笔,是王永民教授于2008年1月28日推出的第三代五笔字型输入法(第一代的86五笔和第二代的98五笔分别于1983年和1998年推出),该版本也被称为标准版王码五笔。新世纪五笔建立在新的字根键位体系,重码实用频度降低,取码更加规范,打字更加顺手,在规律性、易学性等方面有显著的进步。

优点非常多但目前很多输入法软件默认还不支持新世纪五笔,特别是mac系统上的支持更慢一些。我目前主要使用清歌输入法,这个默认可以切换86和98的词库,也支持自定义词库。网络上找到的大部分新世纪词库只有主词库,没有反查功能,新世纪中为了输入的方便性很多字的拆分方式和按键都有变化不能反查真的很不方便。

鉴于此种尴尬情况,我们是否可以自己生成反查词库呢?当然是可以地!

ciku.jpg

思路

首先可以查看系统自带的主词库是这样的:

a 工
aaaa 工 恭恭敬敬
aaad 工期
aaae 黄花菜
aabg 草草了事
aahg 工卡
aahh 工频 茞 茝
aaif 葡萄汁
aaii 落花流水
aaip 工党
aais 葡萄酒 戒酒

一行一条数据前面是输入码后面是可以输入的文字 空格分割。

然后可以查看系统自带的反查词库如下:

㣻   rnu
㣼   nvyy
㣽   vnu
㣾   ncyy
㤈   nny
㤉   naht
㤊   nrry
㤋   nwvt
㤌   nfg

也是一行一条数据,但前面是文字结果后面对应的码。

那根据主词库生成反查词库是不是很清晰了:

  • 读取主词库内容
  • 根据换行符和空格符分割数据为数组
  • 遍历数组生成一个文字对应一个码
  • 结果写入文本文件生成反查词库

功能实现

use std::fs::File;
use std::io::prelude::*;

// 源文件绝对路径
const SOURCE_FILE: &'static str = "/Users/aqrun/xxx/新世纪五笔词库.txt";
// 目标文件绝对路径
const DIST_FILE: &'static str = "/Users/aqrun/xxx/新世纪五笔反查词库.txt";
// 测试用开关控制待处理数据量
const TOTAL: i32 = 100;
// 是否开启控制开关
const LIMIT: bool = false;

fn main() {
    // 获取源文件句柄 file
    let mut file = File::open(SOURCE_FILE).expect("源文件打开失败,请检查文件路径");
    let mut source_data = String::new();
    // 读取源文字内容到 source_data
    file.read_to_string(&mut source_data).expect("源文件内容读取失败");

    // 生成结构化数据
    let res = generate_data(&source_data);
    // 根据结构化数据转为最终文件内容
    let dist_data = generate_file_content(&res);

    // 获取目标文件句柄
    let mut dist_file = File::create(DIST_FILE).expect("目标文件创建失败,请检查路径");
    // 写入内容
    dist_file.write_all(&dist_data.as_bytes()).expect("文件写入失败");
    // println!("{:?}", dist_data);
    println!("转换完成! 共处理{}条数据!", res.len());
}

/**
 * 将源数据字符串转换为结构化的数组数据
 */
fn generate_data(source: &str) -> Vec<Vec<String>> {
    // println!("{:?}", source);
    // 保存所有数据 按行分割原始内容为数组
    let line_data_arr: Vec<&str> = source.split('\n').collect();
    // 保存最后的结果
    let mut res: Vec<Vec<String>> = Vec::new();

    let mut index = 0;
    for i in line_data_arr.iter() {
        index += 1;
        // 测试用控制开关
        if LIMIT && index > TOTAL {
            break;
        }

        if i.is_empty() {
            continue;
        }
        // 按空格分割当前行字符串为数组
        let all_arr: Vec<&str> = i.split(" ").collect();
        // 当前行数据大小
        let len = all_arr.len();
        // 当前行字符编码
        let code = all_arr[0];
        
        for j in 1..len {
            // println!("{:?}, {}, {}, {}", all_arr, len, j, len-2);
            // 将当前行生成为 [编码, 文字] 数组格式 一行一个文字
            let mut res_line: Vec<String> = Vec::new();
            res_line.push(all_arr[j].to_string());
            res_line.push(code.to_string());
            res.push(res_line);
        }
    }
    
    res
}

/**
 * 将结构化数据转为最终文件内容
 */
fn generate_file_content(source_arr: &Vec<Vec<String>>) -> String {
    let mut dist_arr: Vec<String> = Vec::new();
    // println!("res: {:?}", res);

    for i in source_arr {
        dist_arr.push(i.join(" ").to_string());
    }

    dist_arr.join("\n")
}

运行程序

ζ cargo run --bin main                                                                                                             
   Compiling myrust v0.1.0 (/workspace/myrust)
    Finished dev [unoptimized + debuginfo] target(s) in 0.70s
     Running `target/debug/main`
转换完成! 共处理89794条数据!

着不多9W条数据大概用了0.7秒,还是很快的吧应该。

最终生成文件内容类似:

工 a
恭恭敬敬 aaaa
工期 aaad
黄花菜 aaae
工巧 aaag
葡萄牙 aaah
花花世界 aaal
工艺 aaan
工匠 aaar
工区 aaar
工薪 aaau
菚 aaau
斯蒂芬 aaaw

完结!!!

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335

推荐阅读更多精彩内容

  • 目录 1. 输入方案介绍1.1. 新世纪五笔1.2. 新世纪五笔·拼音1.3. 新世纪五笔·简入繁出 2. 依赖 ...
    科研者阅读 9,569评论 1 5
  • 一、概述 声笔飞码,简称飞码,是在输入法界影响最大的顶功输入法,可以说是它直接或者间接地激发了其它非声笔系列顶功输...
    声笔系列阅读 2,415评论 0 0
  • 前提:安装 fcitx RIME安装:$ sudo pacman -S fcitx-rime 注销生效 一些快捷键...
    titvax阅读 1,015评论 0 0
  • 一、概述 声笔快码,简称快码,是一款类双拼输入法,它采用了一种特殊的双拼加笔画编码,同时又融合的 105 个高频声...
    声笔系列阅读 952评论 0 0
  • 虽然见解略有不同,但与 @晓览 的基本观点相同,新世纪五笔是一种比老86、98版都要更差的五笔版本。 与 @晓览 ...
    Ubuntu_2017阅读 9,374评论 4 7