当前位置: 代码迷 >> Web前端 >> java对汉语(拼音)进行排序
  详细解决方案

java对汉语(拼音)进行排序

热度:350   发布时间:2012-08-24 10:00:21.0
java对中文(拼音)进行排序

拼音排序
拼音有好几种方式,其中最主要的是中华人民共和国的汉语拼音 Chinese Phonetic。对汉字的排序有两种:一种是宽松的,能够按拼音排序最常用的汉字,另一种是严格的,能够按拼音排序绝大部分大部分汉字。

宽松的拼音排序法
原理:汉字最早是GB2312编码,收录了六千多个汉字,是按拼音排序的,编码是连续的。 后来出现了GBK编码,对GB2312进行了扩展,到了两万多汉字,并且兼容GB2312,也就是说GB2312中的汉字编码是原封不动搬到GBK中的(在GBK编码中[B0-D7]区中)。

如果我们只关心这6000多个汉字的顺序,就可以用下面的方法实现汉字宽松排序。

/**
* @author shaob
*
* Copyright (c)
*/

package chinese.utility;

import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;

public class PinyinSimpleComparator implements Comparator<String> {
??? public int compare(String o1, String o2) {
??????? return Collator.getInstance(Locale.CHINESE).compare(o1, o2);
??? }
}

在对[孙, 孟, 宋, 尹, 廖, 张, 徐, 昆, 曹, 曾,怡]这几个汉字排序,结果是:[曹, 昆, 廖, 孟, 宋, 孙, 徐, 尹, 曾, 张, 怡]。最后一个 怡 有问题,不该排在最后的。

注意:这个程序有两个不足

由于gb2312中的汉字编码是连续的,因此新增加的汉字不可能再按照拼音顺序插入到已有的gb2312编码中,所以新增加的汉字不是按拼音顺序排的。
同音字比较的结果不等于0 。
下面的测试代码可以证明

/**
* @author shaob
*
* Copyright (c)

/**
* 非常用字(怡)
*/
@Test
public void testNoneCommon() {
??? Assert.assertTrue(comparator.compare("怡", "张") > 0);
}

/**
* 同音字
*/
@Test
public void testSameSound() {
??? Assert.assertTrue(comparator.compare("怕", "帕") != 0);
}

严格的拼音排序法
为了解决宽松的拼音的两点不足,可以通过实现汉语拼音的函数来解决。goolge下看到sf上有个pinyin4j的项目,可以解决这个问题,pinyin4j的项目地址是:http://pinyin4j.sourceforge.net/。

实现代码:

/**
? * @author shaob
? *
? * Copyright (c)
? */
package chinese.utility;

import java.util.Comparator;
import net.sourceforge.pinyin4j.PinyinHelper;

public class PinyinComparator implements Comparator<String> {

??? public int compare(String o1, String o2) {

??????? for (int i = 0; i < o1.length() && i < o2.length(); i++) {

??????????? int codePoint1 = o1.charAt(i);
??????????? int codePoint2 = o2.charAt(i);

??????????? if (Character.isSupplementaryCodePoint(codePoint1)
??????????????????? || Character.isSupplementaryCodePoint(codePoint2)) {
??????????????? i++;
??????????? }

??????????? if (codePoint1 != codePoint2) {
??????????????? if (Character.isSupplementaryCodePoint(codePoint1)
??????????????????????? || Character.isSupplementaryCodePoint(codePoint2)) {
??????????????????? return codePoint1 - codePoint2;
??????????????? }

??????????????? String pinyin1 = pinyin((char) codePoint1);
??????????????? String pinyin2 = pinyin((char) codePoint2);

??????????????? if (pinyin1 != null && pinyin2 != null) { // 两个字符都是汉字
??????????????????? if (!pinyin1.equals(pinyin2)) {
??????????????????????? return pinyin1.compareTo(pinyin2);
??????????????????? }
??????????????? } else {
??????????????????? return codePoint1 - codePoint2;
??????????????? }
??????????? }
??????? }
??????? return o1.length() - o2.length();
??? }

??? /**
???? * 字符的拼音,多音字就得到第一个拼音。不是汉字,就return null。
???? */
??? private String pinyin(char c) {
??????? String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
??????? if (pinyins == null) {
??????????? return null;
??????? }
??????? return pinyins[0];
??? }
}

?

?

转自: http://www.blogjava.net/spinage/archive/2009/09/01.html

?

?

?

?

  相关解决方案