Show me the money
分类: C/C++
2010-02-24 11:31:25
最近需要做一个unicode转gb2312的函数,上网搜索了一下,没有找到特别符合需求的资料。于是乎,只好自己DIY;以下为DIY的心得…
1. 创建gb2312编码表。这个不需要太多的只是,稍微了解一下gb2312的编码规则即可
GB2312将代码表分为94个区,对应第一字节(0xa1-0xfe);每个区94个位(0xa1-0xfe),对应第二字节,两个字节的值分别为区号值和位号值加32(0x20),因此也称为区位码。01-09区为符号、数字区,16-87区为汉字区(0xb0-0xf7),10-15区、88-94区是有待进一步标准化的空白区。 |
2. 将gb2312编码转换成unicode编码,这一步也相当简单,有现成的系统函数可用。在Windows下用MultiByteToWideChar,在Linux下用iconv。
另外提一下,在Windows下一个unicode字符用16位整数表示,但是在linux下unicode是32位的。unicode16和unicode32的关系如何,这个我没有研究;但是凭直觉unicode32应当兼容unicode16,unicode16是unicode32的一个子集。
3. 创建unicode2gb2312的转换表。既然gb2312和unicode的编码表都有了,那么翻译过程就很简单了,就是一个查找/匹配的过程。既然是查找,当然要关注查找效率。虽然只是一个演示程序,也不能太过敷衍了事。(gb2312包含了7000多个字符。)
温习一下课本,里面介绍了很多查找的方法,由于我们始终关注的是查找效率,简单对比一下,平均查找效率最高的大约就是二分法了,时间复杂度为O(log2n)。不过二分法要求数据的元素按照从小到大的顺序排序,怎么办呢?那就排一下序好了,还有现成的库函数,连自己手写个冒泡算法都可以省了。
整理一下思路,我们需要这样一个映射表,这个表由下面的结构组成:
struct uni2gb_entry { uint16_t unicode; uint16_t gbcode; }; |
表的元素以unicode为关键字按照从小到大的顺序排列。查找的时候只要找到与unicode匹配的表项,返回gbcode就可以了。表的大小约为7K*4=28K。查找的效率很高,很实用。
4. 翻译。这就没什么好说的了,二分法查找,BINGO!!
文件:
unicode2gb2312.zip
大小:
13KB
下载:
下载