[open source] 拼音排序函数库发布
2006-09-25 22:40
351 查看
[open source] 拼音排序函数库发布
转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd
作者联系方式:Li XianJing <xianjimli at hotmail dot com>
更新时间:2006-12-19
最近在做资源管理器的设计,SPEC要求中文文件名按拼音排序。于是花了点时间去研究关于拼音排序的问题,然后又花了两小时写了一个函数库。其实知道了原理,按拼音排序的实现很简单,放到这里供大家参考吧。
我们知道,计算机中的每一个字符都有一个内码。在默认情况下,计算机排序时,比较两个字符的大小就是比较字符内码的大小,这对于英文来说没有问题,因为英文字母的内码是按字母顺序递增的。对于中文来说,就比较麻烦了:首先,中文的排序方式有多种,比如按内码排序、按拼音排序和按笔画排序,要通过参数指定排序的方式,否则计算机就按内码排序了。其次,汉字的内码顺序即不同于拼音顺序,也不同于按笔画顺序。在GB2312编码中,汉字基本上按拼音排序(据说有例外,不太清楚)。在GBK中,它在GB2312基础上进行了扩充,兼容GB2312中的所有字符,所以不是按拼音排序了。在Unicode中,汉字的排列似乎更没有什么规律可言了。
为了解决内码顺序与用户习惯顺序(如拼音顺序)的冲突,在glibc的locale数据里,要求提供排序方式(collate)的描述。我看了一下glibc-2.3.5提供的locale数据,在简体中文(zh_CN)的locale数据描述里,关于排序方式的描述如下:
% ISO 14651 collation sequence
LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE
也就是说,照抄iso14651_t1的排序方式。打开iso14651_t1文件看了一下,也没有发现关于中文的特殊处理,可以推断glibc默认的排序方式就是按unicode排序。由此看来,glibc没有提供拼音排序功能,只能由我们自己去实现了。
实现拼音排序其实很简单,我在另外一篇文章中介绍了获得汉字对应拼音的方法,我们可以先取出汉字的拼音然后再比较。这种方法会不会性能低下呢?实际上不会,看起来取拼音过程可能会有点慢,但是一次比较函数调用只需要一次取拼音函数调用,因为只当它们的内码不同时才调用取拼音的函数。
如果仅仅是为了比较汉字的拼音顺序,其实我们可以用更简单的办法,而不必存储那些拼音数据。我们只要预先把所有汉字按拼音排序,汉字在排序后位置偏移量,就可以用来作为比较的基准值。
如何找到所有汉字呢?如果你只需要GB2312中汉字,你可以按我的另外一篇文章里所说的方法去做。如果需要GBK/Unicode中的汉字,GBK和Unicode中的汉字是一一对应的,在Unicode中,汉字所在的区间为0x4e00 - 0x9FA5,所以一个循环就可以打印出所有的汉字。
如何按拼音排序呢?很简单,有很多工具可以完成这一功能,像wps/word/pagemaker/excel。Word排序太慢,而且对行数也有限制,还是用excel吧。
数据如何组织?很简单,建立一张unicode与排序偏移量的映射表就行了。考虑到汉字与非汉字之间的比较,我们需要把偏移量加上0x4e00。考虑到空间问题,0x4e00前面都不是汉字,我们的表只要0x9FA5 - 0x4e00 + 1大小就行了,所以表中的unicode要减去0x4e00。
有兴趣的朋友可以到这里下载。
(如果在程序中即要获取拼音,又要按拼音排序,还是建议用取拼音的方式来比较,那样两个功能的数据可以共享。)
~~end~~
转载时请注明出处和作者联系方式:http://blog.csdn.net/absurd
作者联系方式:Li XianJing <xianjimli at hotmail dot com>
更新时间:2006-12-19
最近在做资源管理器的设计,SPEC要求中文文件名按拼音排序。于是花了点时间去研究关于拼音排序的问题,然后又花了两小时写了一个函数库。其实知道了原理,按拼音排序的实现很简单,放到这里供大家参考吧。
我们知道,计算机中的每一个字符都有一个内码。在默认情况下,计算机排序时,比较两个字符的大小就是比较字符内码的大小,这对于英文来说没有问题,因为英文字母的内码是按字母顺序递增的。对于中文来说,就比较麻烦了:首先,中文的排序方式有多种,比如按内码排序、按拼音排序和按笔画排序,要通过参数指定排序的方式,否则计算机就按内码排序了。其次,汉字的内码顺序即不同于拼音顺序,也不同于按笔画顺序。在GB2312编码中,汉字基本上按拼音排序(据说有例外,不太清楚)。在GBK中,它在GB2312基础上进行了扩充,兼容GB2312中的所有字符,所以不是按拼音排序了。在Unicode中,汉字的排列似乎更没有什么规律可言了。
为了解决内码顺序与用户习惯顺序(如拼音顺序)的冲突,在glibc的locale数据里,要求提供排序方式(collate)的描述。我看了一下glibc-2.3.5提供的locale数据,在简体中文(zh_CN)的locale数据描述里,关于排序方式的描述如下:
% ISO 14651 collation sequence
LC_COLLATE
copy "iso14651_t1"
END LC_COLLATE
也就是说,照抄iso14651_t1的排序方式。打开iso14651_t1文件看了一下,也没有发现关于中文的特殊处理,可以推断glibc默认的排序方式就是按unicode排序。由此看来,glibc没有提供拼音排序功能,只能由我们自己去实现了。
实现拼音排序其实很简单,我在另外一篇文章中介绍了获得汉字对应拼音的方法,我们可以先取出汉字的拼音然后再比较。这种方法会不会性能低下呢?实际上不会,看起来取拼音过程可能会有点慢,但是一次比较函数调用只需要一次取拼音函数调用,因为只当它们的内码不同时才调用取拼音的函数。
如果仅仅是为了比较汉字的拼音顺序,其实我们可以用更简单的办法,而不必存储那些拼音数据。我们只要预先把所有汉字按拼音排序,汉字在排序后位置偏移量,就可以用来作为比较的基准值。
如何找到所有汉字呢?如果你只需要GB2312中汉字,你可以按我的另外一篇文章里所说的方法去做。如果需要GBK/Unicode中的汉字,GBK和Unicode中的汉字是一一对应的,在Unicode中,汉字所在的区间为0x4e00 - 0x9FA5,所以一个循环就可以打印出所有的汉字。
如何按拼音排序呢?很简单,有很多工具可以完成这一功能,像wps/word/pagemaker/excel。Word排序太慢,而且对行数也有限制,还是用excel吧。
数据如何组织?很简单,建立一张unicode与排序偏移量的映射表就行了。考虑到汉字与非汉字之间的比较,我们需要把偏移量加上0x4e00。考虑到空间问题,0x4e00前面都不是汉字,我们的表只要0x9FA5 - 0x4e00 + 1大小就行了,所以表中的unicode要减去0x4e00。
有兴趣的朋友可以到这里下载。
(如果在程序中即要获取拼音,又要按拼音排序,还是建议用取拼音的方式来比较,那样两个功能的数据可以共享。)
~~end~~
相关文章推荐
- [open source] 拼音排序函数库发布
- 谈谈SQL数据库中滥用临时表、排序的解决方案优化(举例:汉字转拼音函数)
- PHP将汉字转化成拼音的函数(用于取首字母索引或按字母排序中文)
- 中文按照拼音排序的函数 strcoll wcscroll 及 _tcscoll
- PHP将汉字转化成拼音的函数(用于取首字母索引或按字母排序中文)
- 来谈谈SQL数据库中滥用临时表、排序的解决方案优化(举例:汉字转拼音函数)
- [DB][ORACLE]根据中文拼音首字母排序、取得中文拼音首字母函数
- 根据中文拼音首字母排序、取得中文拼音首字母函数 oracle 排序
- [open source]通过汉字得到拼音的函数库(getpinyin)发布
- [open source]通过汉字得到拼音的函数库(getpinyin)发布
- 【思路与简介】Hook或改写Javascript脚本的函数,以友言组件为例,发布评论前获取评星和内容
- 发布我的第一个java程序。。用java排序so easy
- 取得汉字字符串的拼音首字母的mssql函数
- oracle order by 拼音排序
- C#排序函数和自定义比较器
- PHP二维数组按照指定的字段排序的函数
- Java 中文拼音 排序
- stl排序函数用户自定义比较函数扩展
- 【Python】Python_learning6:Python中的sort排序函数之序列排序-从小到大&从大到小
- oracle中文(utf8)按拼音排序的简单解决方案