4638|6

849

帖子

0

TA的资源

纯净的硅(高级)

楼主
 

一级汉字拼音输入法的实现 [复制链接]

Boyi©电子实验室

手机输入法一级汉字算法

 

为了使每一个汉字有一个全国统一的代码,1980年,我国颁布了第一个汉字编码的国家标准:GB2312-80《信息交换用汉字编码字符集》基本集,这个字符集是我国中文信息处理技术的发展基础,也是目前国内所有汉字系统的统一标准。到了后来又公布了国家标准GB18030-2000《信息交换用汉字编码字符集基本集的扩充》,简称GB18030。由于国标码是四位十六进制,为了便于交流,大家常用的是四位十进制的区位码。所有的国标汉字与符号组成一个94×94的矩阵。在此方阵中,每一行称为一个"",每一列称为一个"",因此,这个方阵实际上组成了一个有94个区(区号分别为0 194)、每个区内有94个位(位号分别为0194)的汉字字符集。一个汉字所在的区号和位号简单地组合在一起就构成了该汉字的"区位码"。在汉字的区位码中,高两位为区号,低两位为位号。在区位码中,01-09区为682个特殊字符,16-87区为汉字区,包含6763个汉字 。其中16-55区为一级汉字(3755个最常用的汉字,按拼音字母的次序排列)56-87区为二级汉字(3008个汉字,按部首次序排列)


   
从汉字到区位码的转换。区位码是与汉字一一对应的编码,用四位数字表示 前两位从01 94称区码,后两位从0194称位码。 一个汉字的前一半为“160+区码”的字符,后一半为“160 位码”的字符。例如:“刘”的区位码是 3385,其意为区码33位码85,它是由16033=19316085=245的两个字节组成。即 0xC1F5,它就是汉字的 gb2312 编码。

 

从上面可以看出,区码+160就是汉字的高位字节,位码+160就是汉字的低位字节

 

最新回复

强!  详情 回复 发表于 2011-12-23 12:39
 
点赞 关注
个人签名只有想不到,没有做不到。

回复
举报

849

帖子

0

TA的资源

纯净的硅(高级)

沙发
 

回复 楼主 shilaike 的帖子

标准Unicode库的汉字解析函数:

/*

*从nandflash中读取字库数据   :576为一个字符的数据量;返回点阵开始的位置

*/

u32 getWordDataFromNandFlash(u8 *tmpbuffer, u8 * ptr, fonts fontType)

{

         u32 retNum = 0;

         u32 code1 = *ptr, code2 = 0; /* code1放的是区码,而code2放的是位码 */

         NAND_ADDRESS WriteReadAddrTmp1;

         switch (fontType) {

                            case font_12:

                                     if (code1 < 0x80) {

                                               WriteReadAddrTmp1.Zone = 0;

                                               WriteReadAddrTmp1.Block = ASC12_STORE_START_BLOCK;

                                               WriteReadAddrTmp1.Page = 0;

                                               retNum = (code1-32) * 12;

                                     } else {

                                               WriteReadAddrTmp1.Zone = 0;

                                               WriteReadAddrTmp1.Block = HZK12_STORE_START_BLOCK;

                                               WriteReadAddrTmp1.Page = 0;

                                               code2 = *(ptr + 1); /* 获取汉字位码 */

                                               retNum = ((code1-0xa1) * 94 + (code2-0xa1)) * 24;

                                     }                                    

                                     break;

                            case font_16:            //8*16ASCII码/16*16汉字

                                     if (code1 < 0x80) {

                                               if(code1 == '^')

                                               {                                                       //上标显示

                                                        code1 = *(ptr   + 1);

                                                        WriteReadAddrTmp1.Zone = 0;

                                                        WriteReadAddrTmp1.Block = ASC12_STORE_START_BLOCK;

                                                        WriteReadAddrTmp1.Page = 0;

                                                        retNum = (code1-32) * 12;

                                                        break;

                                               }else if(code1 == '~')

                                               {

                                                        code1 = *(ptr   + 1);

                                                        {

                                                                 WriteReadAddrTmp1.Zone = 0;

                                                                 WriteReadAddrTmp1.Block = ASC12_STORE_START_BLOCK;

                                                                 WriteReadAddrTmp1.Page = 0;

                                                                 retNum = (code1-32) * 12;

                                                        }

                                                       break;

                                               }

                                     } else {

                                               code2 = *(ptr + 1);

                                               WriteReadAddrTmp1.Zone = 0;

                                               WriteReadAddrTmp1.Block = ZHK16_STORE_START_BLOCK;

                                               WriteReadAddrTmp1.Page = 0;

                                               retNum = ((code1-0xa1) * 94 + (code2-0xa1)) * 32;

                                     }

                                     break;

                            case font_24:            //16*24ASCII码/24*24汉字

                                     if (code1 < 0x80) {



                                     } else {

                                               code2 = *(ptr + 1);

                                               WriteReadAddrTmp1.Zone = 0;

                                               WriteReadAddrTmp1.Block = ZHK24_STORE_START_BLOCK;

                                               WriteReadAddrTmp1.Page = 0;

                                               retNum = ((code1-0xb0) * 94 + (code2-0xa1)) * 72;

                                     }

                                     break;

                            case font_48:            //24*48ASCII码

                                     if (code1 < 0x80) {

                                                       WriteReadAddrTmp1.Zone = 0;

                                                        WriteReadAddrTmp1.Block = ASC48_STORE_START_BLOCK;

                                                        WriteReadAddrTmp1.Page = 0;

                                                        retNum = (code1-32) * 144;

                                     }

                                     break;

                   /*case font_96:

                   {        

                            WriteReadAddrTmp1.Zone = 0;

                            WriteReadAddrTmp1.Block = _4896_STORE_START_BLOCK;

                            WriteReadAddrTmp1.Page = 0;

         

                            if(code1 == '+')

                            {

                                     retNum = 0;

                            }

                            else if(code1 == '-')

                            {

                                     retNum = 576;

                            }

                            else if(code1 >= '0' && code1 <= '9')

                            {

                                     retNum = (code1 - '0' + 2) * 576 ;

                            }

                            else if(code1 == '.')

                            {

                                     retNum = 12 * 576;

                            }else if(code1 >= 'A' && code1 <= 'Z')

                            {

                                     retNum = (code1 - 'A' + 13) * 576;

                            }

                   }*/

                   default :

                            break;

         }

         WriteReadAddrTmp1.Page = retNum/NAND_PAGE_SIZE;

         {

                   u16  tmpBlock = WriteReadAddrTmp1.Page / NAND_BLOCK_SIZE,i = 0;

                   for(;i <= tmpBlock; i++) {  

                             if(checkNandFlashBlockState(WriteReadAddrTmp1))

                                    tmpBlock ++;

                             WriteReadAddrTmp1.Block ++;

                   }

                   WriteReadAddrTmp1.Block --;

         }

         WriteReadAddrTmp1.Page %= NAND_BLOCK_SIZE;

         retNum %= NAND_PAGE_SIZE;

         FSMC_NAND_ReadSmallPage(tmpbuffer,WriteReadAddrTmp1,2);

         return retNum;

}

与现在主流的方法一样,利用查表结构实现拼音输入法:(以部分汉字为例,我将全部的一级汉字加到工程里面了,坛友有需要可以联系)

1.拼音结构的实现

结构体的实现:

typedef struct {
unsigned char str[5];
unsigned char bit_code;
unsigned char zone_code;

}PY_index;


typedef PY_index *pointer;



然后看所有一级汉字拼音的指针数组结构:


pointer PY_index_pointer[]={
PY_index_a, PY_index_b,PY_index_c,PY_index_d,PY_index_e,PY_index_f,PY_index_g,PY_index_h,
PY_index_j,PY_index_j,PY_index_k,PY_index_l,PY_index_m,PY_index_n,PY_index_o,PY_index_p,
PY_index_q,PY_index_r,PY_index_s,PY_index_t,PY_index_w,PY_index_w,PY_index_w,PY_index_x,
PY_index_y,PY_index_z,PY_index_end
};

/* 拼音输入法查询码表 ,只给出以a和b开关的拼音表 */
_index PY_index_a[] = {
{"", 0x00, 0x00},
{"i  ", 0x08, 0x00},
{"n  ", 0x24, 0x00},
{"ng ", 0x33, 0x00},
{"o  ", 0x3a, 0x00},
};

PY_index PY_index_b[]={
{"a  ",0x4D,0x00},
{"ai ",0x70,0x00},
{"an ",0x81,0x00},
{"ang",0xA0,0x00},
{"ao ",0xB9,0x00},
{"ei ",0xDE,0x00},
{"en ",0xFD,0x00},
{"eng",0x08,0x01},
{"i  ",0x15,0x01},
{"ian",0x44,0x01},
{"iao",0x5D,0x01},
{"ie ",0x66,0x01},
{"in ",0x6F,0x01},
{"ing",0x7C,0x01},
{"o  ",0x8F,0x01},
{"u  ",0xB8,0x01},
};



汉字码表的建立:

//"拼音输入法汉字排列表,只给出a和开头的汉字一级表
unsigned char PY_mb_a     []={"阿啊"};   
unsigned char PY_mb_ai    []={"哎哀唉埃挨皑癌矮蔼艾爱隘碍"};   
unsigned char PY_mb_an    []={"安氨鞍俺岸按案胺暗"};   
unsigned char PY_mb_ang   []={"肮昂盎"};   
unsigned char PY_mb_ao    []={"凹敖熬翱袄傲奥澳懊"};   
unsigned char PY_mb_ba    []={"八巴叭扒吧芭疤捌笆拔跋把靶坝爸罢霸"};   
unsigned char PY_mb_bai   []={"白百佰柏摆败拜稗"};   
unsigned char PY_mb_ban   []={"扳班般颁斑搬板版办半伴扮拌绊瓣"};   
unsigned char PY_mb_bang  []={"邦帮梆绑榜膀蚌傍棒谤磅镑"};   
unsigned char PY_mb_bao   []={"包苞胞褒雹宝饱保堡报抱豹鲍暴爆剥薄瀑"};   
unsigned char PY_mb_bei   []={"卑杯悲碑北贝狈备背钡倍被惫焙辈"};   
unsigned char PY_mb_ben   []={"奔本苯笨夯"};   
unsigned char PY_mb_beng  []={"崩绷甭泵迸蹦"};   
unsigned char PY_mb_bi    []={"逼鼻比彼笔鄙币必毕闭庇毖陛毙敝痹蓖弊碧蔽壁避臂"};   
unsigned char PY_mb_bian  []={"边编鞭贬扁卞便变遍辨辩辫"};   
unsigned char PY_mb_biao  []={"彪标膘表"};   
unsigned char PY_mb_bie   []={"憋鳖别瘪"};   
unsigned char PY_mb_bin   []={"宾彬斌滨濒摈"};   
unsigned char PY_mb_bing  []={"冰兵丙秉柄炳饼并病"};   
unsigned char PY_mb_bo    []={"拨波玻钵脖菠播伯驳帛泊勃铂舶博渤搏箔膊卜"};   
unsigned char PY_mb_bu    []={"补哺捕不布步怖部埠簿"};



拼音解析函数:

//"拼音输入法杳询函数,input_py为已输入的拼音码,反回值为中文的起始地址,当为0时,杳询失败"   

unsigned char code * py_ime(unsigned char input_py_val[]);   

   
//"========================================主程序体========================================"   
   
unsigned char code * py_ime(unsigned char input_py_val[])   
{   
    unsigned char code (* xdata p1)[8],(* xdata p2)[8],(* xdata p3)[8];   
    unsigned char xdata i=1;   
    if (input_py_val[0]==0) return(0);                                                                              //"如果输入空字符返回0"   
    if (input_py_val[0]=='i') return(0);   
    if (input_py_val[0]=='u') return(0);   
    if (input_py_val[0]=='v') return(0);   
    p1=p2=PY_index_pointer[input_py_val[0]-0x61];                                                           //"计算入口树根"   
    p3=PY_index_pointer[input_py_val[0]-0x60];                                                              //"设置指针界限"   
    if (p1==0) return(0);                                                                                                           //"查询失败返回0"   
    while (p1     p1=p2;   
    while (p1         if (((*p1)==input_py_val[i+1])&&((*p1)[i-1]==input_py_val))   
        {   
            p2=p1;   
            i++;   
        }   
        else p1++;   
    return((unsigned char code *)((*p2)[6]+(*p2)[7]*256+py_mb_begin));              //"返回查询结果首地址"   
}
测试函数:上位机测试(注意:window下的字符串实际占用的空间数与理论上的占用数是有差距的,请结合实际查看)

int main(void)
{
unsigned char pinyin[] = {"an"};

unsigned char pinyin1[]={"ai"};
unsigned char chinese_string[100]={0};

unsigned char chinese_string1[100]={0};
sprintf(chinese_string, "%s", py_ime(pinyin));

sprintf(chinese_string1, "%s", py_ime(pinyin1));

printf("%s\n", chinese_string);
return 0;
}

显示结果请看图:
 
个人签名只有想不到,没有做不到。
 

回复

849

帖子

0

TA的资源

纯净的硅(高级)

板凳
 

结果请看:

 

[ 本帖最后由 shilaike 于 2011-12-14 13:45 编辑 ]

1.jpg (24.8 KB, 下载次数: 0)

1.jpg
 
个人签名只有想不到,没有做不到。
 
 

回复

27

帖子

0

TA的资源

一粒金砂(中级)

4
 
不错 学习了
 
 
 

回复

1803

帖子

0

TA的资源

五彩晶圆(高级)

5
 

回复 板凳 shilaike 的帖子

多谢分享!:carnation:
 
 
 

回复

3404

帖子

6

TA的资源

裸片初长成(初级)

6
 
楼主 辛苦啦:carnation:
 
 
 

回复

139

帖子

0

TA的资源

一粒金砂(中级)

7
 
强!
 
个人签名店铺:http://mcuc.taobao.com;单片机视频教程资料
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/9 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表