浦乐 发表于 2025-11-11 17:00:17

人人能看懂的智能拼音输入法源码及数据,不到300行C++

全部文件的行数

   720 gb2312.utf8
   16463 hz-py.utf8
2894733 slm.arpa # 文本文件格式的语言模型

      15 h.h
   125 ime.cpp
   109 pinyin.cpp
      44 seg.cpp
      17 Makefile

      63 mk-bin.py〔百度网盘下载 .7z 17M〕提取码: 243u
语料:别人的词典
语言模型工具:KenSLM
模型:GB2312汉字的2-gram; 未做prune
存储:SQLite. 严正声明:本人会写二分搜索和用Python排序。 :-) 

[*]SQLite生成的数据库111M,如果把索引开全,139M,速度还不快
[*]我在KenSLM 里幻想了一通各种优化
NT何意?No Threshold; Nuclear/No Threat; New Technology,都与我不再有关。
-lsqlite3 -lreadline即可,这两个都是系统默认安装的。
seg *.txt 分字 (把字用空格隔开)。输出到stdout,可 >,可 | 给KenSLM,它抱怨不能mmap,使用慢速 read.
mk-bin.py 把 hz-py.utf8 和 slm.arpa 转成 slm.bin
ime用slm.bin,输入行可编辑(用了readline)。源码摘抄:
int main () {
for (string s; (s = input()).size(); _slm.predict(s));
return 0;
}

void SLM::predict (const string& s) {
_m.resize(0);
for (const auto& py : break_pystr(s.c_str())) _m.emplace_back(get_column(py));
if (!_m.size()) return;
for (const auto& v : _m) if (!v.size()) return;
viterbi(), print();
}

void SLM::viterbi () 第70~第92行

struct SLM {
vector<vector<Token>> _m; // matrix (lattice)
vector<int> _path;

vector<Token> get_column(const string& py);
double bigram(int x, int y, int y2);
void viterbi();
void print();
void predict(const string& s);
};

struct Token { // 抄全了
Token (const uint8_t* s) { memcpy(hz, s, 4); } // *(int*)... ARM上字节对齐问题...
bool operator< (const Token& that) const { return prob > that.prob; }
charhz; // UTF-8
double prob, bop; // 1-gram; backoff probability/penalty
double max;
int from;
};〔如何在Windows下开发输入法:Mini How-to〕

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

穆望 发表于 2025-12-1 02:25:04

分享、互助 让互联网精神温暖你我
页: [1]
查看完整版本: 人人能看懂的智能拼音输入法源码及数据,不到300行C++