美文网首页
Rust 实现新世纪五笔反查词库

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

作者: 子十一刻 | 来源:发表于2022-04-06 20:53 被阅读0次

背景

新世纪版五笔字型输入法,简称新世纪五笔,是王永民教授于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

完结!!!

相关文章

网友评论

      本文标题:Rust 实现新世纪五笔反查词库

      本文链接:https://www.haomeiwen.com/subject/vjjdsrtx.html