现在智能拼音输入那么高级智能,可是你知道它的程序的原理吗? 我以前也不知道,后来无意间自己“领悟”了大概的原理,写出来跟大家分享一下,文章有错的可以指正,有这方面经验的人懂更多的也可以分享一下。
那拼音输入法到底是怎么一个原理呢?现在就讲讲流程。
一 首先要知道“汉字编码”。这里只讲拼音(音码),用GB2312编码举例,其他编码,部首输入法等同理(扩展形码(五笔,部首))。
参考http://baike.baidu.com/view/1204863.htm?fr=aladdin
GB2312 编码
第16-55区 | 一级汉字(以拼音字母排序) |
第56-87区 | 二级汉字(以部首笔画排序) |
每个汉字或图形符号分别用两位的十进制区码(行码)和两位的十进制位码(列码)表示,不足的地方补0,组合起来就是区位码。 把区位码按一定的规则转换成的二进制代码叫做信息交换码(简称国标码)。国标码共有汉字6763个(一级汉字,是最常用的汉字,按汉语拼音字母顺序排列,共3755个; 二级汉字,属于次常用汉字,按偏旁部首的笔划顺序排列,共3008个),数字、字母、符号等682个,共7445个。
所有16-87区都汉字编码,每一区里有按编码分位,当然这里的编码是有规律的。
用PHP 代码演示
/** * 遍历所有一级字 ,二级字同理, */ public function areaPos() { $i = 1; for($area = 0xb0; $area <= 0xf7; $area++){ for($pos = 0xa1; $pos <= 0xfe; $pos++){ echo iconv('GB2312', 'UTF-8', chr($area) . chr($pos)) . ' ' . (($area << 8) + $pos - 65536) . "\n"; if($i++ == 3755){ echo "一级字到此结束\n"; echo $area . "\n"; echo $pos . "\n"; exit; } } } }
从16区01位是“啊”然后 都是拼音“a”的汉字然后是拼音“ai”....
"a|ai|an|ang|ao|ba|bai|ban|bang|bao|bei|ben|beng|bi|bian|biao|bie|bin|bing|bo|bu|ca|cai|can|cang|cao|ce|ceng|cha" .
"|chai|chan|chang|chao|che|chen|cheng|chi|chong|chou|chu|chuai|chuan|chuang|chui|chun|chuo|ci|cong|cou|cu|" .
"cuan|cui|cun|cuo|da|dai|dan|dang|dao|de|deng|di|dian|diao|die|ding|diu|dong|dou|du|duan|dui|dun|duo|e|en|er" .
"|fa|fan|fang|fei|fen|feng|fo|fou|fu|ga|gai|gan|gang|gao|ge|gei|gen|geng|gong|gou|gu|gua|guai|guan|guang|gui" .
"|gun|guo|ha|hai|han|hang|hao|he|hei|hen|heng|hong|hou|hu|hua|huai|huan|huang|hui|hun|huo|ji|jia|jian|jiang" .
"|jiao|jie|jin|jing|jiong|jiu|ju|juan|jue|jun|ka|kai|kan|kang|kao|ke|ken|keng|kong|kou|ku|kua|kuai|kuan|kuang" .
"|kui|kun|kuo|la|lai|lan|lang|lao|le|lei|leng|li|lia|lian|liang|liao|lie|lin|ling|liu|long|lou|lu|lv|luan|lue" .
"|lun|luo|ma|mai|man|mang|mao|me|mei|men|meng|mi|mian|miao|mie|min|ming|miu|mo|mou|mu|na|nai|nan|nang|nao|ne" .
"|nei|nen|neng|ni|nian|niang|niao|nie|nin|ning|niu|nong|nu|nv|nuan|nue|nuo|o|ou|pa|pai|pan|pang|pao|pei|pen" .
"|peng|pi|pian|piao|pie|pin|ping|po|pu|qi|qia|qian|qiang|qiao|qie|qin|qing|qiong|qiu|qu|quan|que|qun|ran|rang" .
"|rao|re|ren|reng|ri|rong|rou|ru|ruan|rui|run|ruo|sa|sai|san|sang|sao|se|sen|seng|sha|shai|shan|shang|shao|" .
"she|shen|sheng|shi|shou|shu|shua|shuai|shuan|shuang|shui|shun|shuo|si|song|sou|su|suan|sui|sun|suo|ta|tai|" .
"tan|tang|tao|te|teng|ti|tian|tiao|tie|ting|tong|tou|tu|tuan|tui|tun|tuo|wa|wai|wan|wang|wei|wen|weng|wo|wu" .
"|xi|xia|xian|xiang|xiao|xie|xin|xing|xiong|xiu|xu|xuan|xue|xun|ya|yan|yang|yao|ye|yi|yin|ying|yo|yong|you" .
"|yu|yuan|yue|yun|za|zai|zan|zang|zao|ze|zei|zen|zeng|zha|zhai|zhan|zhang|zhao|zhe|zhen|zheng|zhi|zhong|" .
"zhou|zhu|zhua|zhuai|zhuan|zhuang|zhui|zhun|zhuo|zi|zong|zou|zu|zuan|zui|zun|zuo"
然后表这个表做个映射,当键盘按下“a”的时候,就从16区01位开始显示几个汉字让选择,并记录用户选择的情况,以后按照选择次数多的排序,达到比较智能点。当然智能拼音还有词组记录,常用词等等。有很多种智能策略……。
最简单的输入法流程:
键盘按个一个键,程序获取ASCII码,知道是哪个字符,根据这个字符去“音码表”查找,显示出用户经常选择的字,词,根据用户选择,输出到屏幕输入框。
/** * 判断1,2级字 */ public function test() { $c = "啊"; $c = iconv('UTF-8', 'GB2312', $c); echo (ord(substr($c, 0, 1)) - 160) . "\n"; $c = "鲨"; $c = iconv('UTF-8', 'GB2312', $c); $num = ord(substr($c, 0, 1)) * 256 + ord(substr($c, 1, 1)); echo $num . ' ' . ($num - 65536) . "\n"; if($num > (0xD7 << 8 + 0xF9)){ echo '2级'; } else{ echo '1级'; } }