Java漢字ソート(2)ピンイン順
21034 ワード
1.はじめに
漢字を含む文字列のソート方法は、主に2つあります.
一つはピンインで、一つは筆画です.
ピンイン順のコンパレータ(Comparator)の実装方法について説明します.
作者:Jeff 2007年12月21日11:27最終更新日: 2007年12月21日12:38 著作権声明:任意に転載することができて、転載する時必ずハイパーリンクの形式で文章の原始の出所と作者の情報と本著作権声明を明記してください. http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html
2.ピンインのソート
ピンインにはいくつかの方法がありますが、その中で最も主要なのは中華人民共和国の中国語ピンインChinese Phoneticです.漢字の並べ替えには2種類あります.1つはゆとりがあり、ピンインで最もよく使われる漢字を並べ替えることができ、もう1つは厳格で、ピンインでほとんどの漢字を並べ替えることができます.
2.1ゆったりしたピンインソート
原理:漢字は一番早くGB 2312コードで、六千余りの漢字を収録して、ピンイン順に並べて、コードは連続しています.後にGBK符号化が出現し、GB 2312が拡張され、2万以上の漢字が得られ、かつGB 2312に対応している、すなわちGB 2312における漢字符号化はそのままGBKに移されている(GBK符号化における[B 0-D 7]領域).
この6000以上の漢字の順序だけに関心があれば、以下の方法で漢字のゆとりソートを実現することができます.
「孫、孟、宋、尹、廖、張、徐、昆、曹、曽、怡」という漢字を並べ替えた結果、「曹、昆、廖、孟、宋、孫、徐、尹、曽、張、怡」となった.最後の 怡 問題があって、最後に並ぶべきではありません.
注意:このプログラムには2つの不足があります. gb 2312の漢字符号化は連続しているため、新たに増加した漢字が既存のgb 2312符号化にピンイン順に挿入されることは不可能であるため、新たに増加した漢字はピンイン順に並べられていない. 同音字比較の結果は0に等しくない.
次のテストコードは証明できます.
2.2厳格なピンインソート法
ゆったりしたピンインの2点不足を解決するために,中国語のピンインの関数を実現することで解決できる.goolgeの下でsfにpinyin 4 jのプロジェクトがあるのを見て、この問題を解決することができて、pinyin 4 jのプロジェクトの住所は:http://pinyin4j.sourceforge.net/.
実装コード:
3.テスト
このような厳格なピンインのソートには改善すべき点があり、上のテストコードの最後のテストを見ると、プログラムは文脈に基づいて多音字のピンインを判断することはなく、単純に多音字の最初のピンインを取るだけであることがわかります.
転載先:https://www.cnblogs.com/sjjg/p/4928777.html
漢字を含む文字列のソート方法は、主に2つあります.
一つはピンインで、一つは筆画です.
ピンイン順のコンパレータ(Comparator)の実装方法について説明します.
作者:Jeff 2007年12月21日11:27最終更新日: 2007年12月21日12:38 著作権声明:任意に転載することができて、転載する時必ずハイパーリンクの形式で文章の原始の出所と作者の情報と本著作権声明を明記してください. http://www.blogjava.net/jeff-lau/archive/2007/12/21/169257.html
2.ピンインのソート
ピンインにはいくつかの方法がありますが、その中で最も主要なのは中華人民共和国の中国語ピンインChinese Phoneticです.漢字の並べ替えには2種類あります.1つはゆとりがあり、ピンインで最もよく使われる漢字を並べ替えることができ、もう1つは厳格で、ピンインでほとんどの漢字を並べ替えることができます.
2.1ゆったりしたピンインソート
原理:漢字は一番早くGB 2312コードで、六千余りの漢字を収録して、ピンイン順に並べて、コードは連続しています.後にGBK符号化が出現し、GB 2312が拡張され、2万以上の漢字が得られ、かつGB 2312に対応している、すなわちGB 2312における漢字符号化はそのままGBKに移されている(GBK符号化における[B 0-D 7]領域).
この6000以上の漢字の順序だけに関心があれば、以下の方法で漢字のゆとりソートを実現することができます.
1 /**
2 * @author Jeff
3 *
4 * Copyright (c) , 。
5 */
6
7 package chinese.utility;
8
9 import java.text.Collator;
10 import java.util.Comparator;
11 import java.util.Locale;
12
13 public class PinyinSimpleComparator implements Comparator {
14 public int compare(String o1, String o2) {
15 return Collator.getInstance(Locale.CHINESE).compare(o1, o2);
16 }
17 }
「孫、孟、宋、尹、廖、張、徐、昆、曹、曽、怡」という漢字を並べ替えた結果、「曹、昆、廖、孟、宋、孫、徐、尹、曽、張、怡」となった.最後の 怡 問題があって、最後に並ぶべきではありません.
注意:このプログラムには2つの不足があります.
次のテストコードは証明できます.
1 /**
2 * @author Jeff
3 *
4 * Copyright (c) , 。
5 */
6
7 /**
8 * ( )
9 */
10 @Test
11 public void testNoneCommon() {
12 Assert.assertTrue(comparator.compare(" ", " ") > 0);
13 }
14
15 /**
16 *
17 */
18 @Test
19 public void testSameSound() {
20 Assert.assertTrue(comparator.compare(" ", " ") != 0);
21 }
2.2厳格なピンインソート法
ゆったりしたピンインの2点不足を解決するために,中国語のピンインの関数を実現することで解決できる.goolgeの下でsfにpinyin 4 jのプロジェクトがあるのを見て、この問題を解決することができて、pinyin 4 jのプロジェクトの住所は:http://pinyin4j.sourceforge.net/.
実装コード:
1 /**
2 * @author Jeff
3 *
4 * Copyright (c) , 。
5 */
6 package chinese.utility;
7
8 import java.util.Comparator;
9 import net.sourceforge.pinyin4j.PinyinHelper;
10
11 public class PinyinComparator implements Comparator {
12
13 public int compare(String o1, String o2) {
14
15 for (int i = 0; i < o1.length() && i < o2.length(); i++) {
16
17 int codePoint1 = o1.charAt(i);
18 int codePoint2 = o2.charAt(i);
19
20 if (Character.isSupplementaryCodePoint(codePoint1)
21 || Character.isSupplementaryCodePoint(codePoint2)) {
22 i++;
23 }
24
25 if (codePoint1 != codePoint2) {
26 if (Character.isSupplementaryCodePoint(codePoint1)
27 || Character.isSupplementaryCodePoint(codePoint2)) {
28 return codePoint1 - codePoint2;
29 }
30
31 String pinyin1 = pinyin((char) codePoint1);
32 String pinyin2 = pinyin((char) codePoint2);
33
34 if (pinyin1 != null && pinyin2 != null) { //
35 if (!pinyin1.equals(pinyin2)) {
36 return pinyin1.compareTo(pinyin2);
37 }
38 } else {
39 return codePoint1 - codePoint2;
40 }
41 }
42 }
43 return o1.length() - o2.length();
44 }
45
46 /**
47 * , 。 , return null。
48 */
49 private String pinyin(char c) {
50 String[] pinyins = PinyinHelper.toHanyuPinyinStringArray(c);
51 if (pinyins == null) {
52 return null;
53 }
54 return pinyins[0];
55 }
56 }
3.テスト
1 /**
2 * @author Jeff
3 *
4 * Copyright (c) , 。
5 */
6 package chinese.utility.test;
7
8 import java.util.Comparator;
9
10 import org.junit.Assert;
11 import org.junit.Test;
12
13 import chinese.utility.PinyinComparator;
14
15 public class PinyinComparatorTest {
16
17 private Comparator comparator = new PinyinComparator();
18
19 /**
20 *
21 */
22 @Test
23 public void testCommon() {
24 Assert.assertTrue(comparator.compare(" ", " ") < 0);
25 }
26
27 /**
28 *
29 */
30 @Test
31 public void testDifferentLength() {
32 Assert.assertTrue(comparator.compare(" ", " ") < 0);
33 }
34
35 /**
36 *
37 */
38 @Test
39 public void testNoneChinese() {
40 Assert.assertTrue(comparator.compare("a", " ") < 0);
41 Assert.assertTrue(comparator.compare("1", " ") < 0);
42 }
43
44 /**
45 * ( )
46 */
47 @Test
48 public void testNoneCommon() {
49 Assert.assertTrue(comparator.compare(" ", " ") < 0);
50 }
51
52 /**
53 *
54 */
55 @Test
56 public void testSameSound() {
57 Assert.assertTrue(comparator.compare(" ", " ") == 0);
58 }
59
60 /**
61 * ( )
62 */
63 @Test
64 public void testMultiSound() {
65 Assert.assertTrue(comparator.compare(" ", " ") > 0);
66 }
67
68 }
このような厳格なピンインのソートには改善すべき点があり、上のテストコードの最後のテストを見ると、プログラムは文脈に基づいて多音字のピンインを判断することはなく、単純に多音字の最初のピンインを取るだけであることがわかります.
転載先:https://www.cnblogs.com/sjjg/p/4928777.html