zoukankan      html  css  js  c++  java
  • Java比较汉字字符串排序与C++比较汉字排序

    一、Java比较汉字

    // Collator 类是用来执行区分语言环境的 String 比较的,这里选择使用CHINA         

    Comparator cmp = Collator.getInstance(java.util.Locale.CHINA); 

    TreeMap tree=new TreeMap(cmp);     

      String[] arr = {"张三", "李四", "王五"};       

    // 使根据指定比较器产生的顺序对指定对象数组进行排序。      

       Arrays.sort(arr, cmp);      

      for (int i = 0; i < arr.length; i++)         

        System.out.println(arr[i]);

    <script>
     names = ["张三", "李四", "王五", "刘六"];
     names.sort(function(a,b){return a.localeCompare(b)});//a,b 为数组a的某两个值,自动传入
     alert(names);
    </script>

    另:

    示例文本:



    String [] test = new String[] {
                    "作业",
                    "测试",
                    "test",
                    "我们",
                    "。空",
                    "镂空",
                    "[",
                    "浏",
                    "皙"
            };

    jdk 版本:

     1.5.6

    开发平台:

     Eclipse 3.1

    关键字: 中文排序

    概述


    我们在应用程序中可能会经常遇到对中文排序的问题,例如姓名列表,词汇表等等。对中文排序,我们使用比较多的是根据汉语拼音发音来确定顺序。

    我们可能会经常使用 

    1. java.util.Set

     接口,

    1. java.util.Arrays .sort((T[] a, Comparator <? super  T> c))

     等类或方法对含有中文字符的对象进行排序,但是这些在默认情况下都是调用 

    1. String .CompareTo(String )

    方法,这个方法是比较2个字符的 codepoint value,如果第一个字符的值小于第二个,则在排序结果中第一个会在前面,反之亦然。

    1. java.text.Collator
    接口及其实现类


    其实 java 中提供了和语言相关的类,即 Collator 接口及其实现类。

     是一个具体类,它实现了 Comparator 接口中的 compare(Object, Object) 方法。 RuleBasedCollator 根据根据特定语言的默认规则比较字符,也可以按照指定的规则来比较,请参阅 java API 获取此类的详细信 息。
    如果我们需要对一个有中文的数组进行排序,则可以使用这个类。请看如下示例代码:

    1. import  java.util.*;
    2. import  java.text.*;
    3. public  class  Test
    4. {
    5.         String  [] test = new  String [] {
    6.                 "作业" ,
    7.                 "测试" ,
    8.                 "test" ,
    9.                 "我们" ,
    10.                 "。空" ,
    11.                 "镂空" ,
    12.                 "[" ,
    13.                 "浏" ,
    14.                 "皙"
    15.         };
    16.       java.util.Arrays .sort(test, 
    17.               (RuleBasedCollator )Collator .getInstance(Locale .CHINA));
    18.       System .out.println("============" );
    19.       for (String  key : test)
    20.           System .out.println(key);
    21. }



    以上代码的输出结果为:

    ============
    [
    test
    。空
    测试
    我们
    作业

    镂空



    大家可能会发现只有一部分汉字是按照汉语拼音排序了,还有几个没有。

    问题分析:


    GB2312:
    在简体中文中我们使用比较多的字符集是 GB2312-80,简称为 GB2312,这个字符集包含了目前最常用的汉字共计 6736 个。其中的汉字分为两大类:

    • 常用汉字
    • 次常用汉字



    常用汉字按照汉语拼音来排序,而次常用汉字按照笔画部首进行排序。

    简体汉字在 Unicode 中一般是按照 gb2312 的码点值的顺序来放置的,所以如果是常用汉字 java 就能够很准确的进行排序,但如果是次常用汉字,则就会出现问题。在以上示例中,"镂","皙" 属于次常用字。

    解决方案:


    RuleBasedCollator 类 getRules() 方法可以返回对应语言的规则设置。简体中文对应的规则是 gb2312 所对应的字符。


    1. 我们可以把其中的全部汉字提取出来
    1. 对这些汉字重新排序
    1. 利用RuleBasedCollator(String rules) 构造器新建一个定制的 RuleBasedCollator

    参考代码


    在以下的代码中,我把排过序的汉字直接作为 String 对象放在类里面了,如果要让代码变得简洁一些,则可以把完整的规则(特殊字符+排序汉字)存为文件。

    1. package  sorting;
    2. import  java.util.*;
    3. import  java.text.*;
    4. /**
    5.  * @author GaoJianMin
    6.  *
    7.  */
    8. public  class  ChineseGB2312Collator
    9. {
    10.     /**
    11.      * @return a customized RuleBasedCollator with Chinese characters (GB2312) sorted correctly
    12.      * 
    13.      */
    14.     public  static  final  RuleBasedCollator  getFixedGB2312Collator()
    15.     {
    16.         RuleBasedCollator  fixedGB2312Collator =null ;
    17.         try
    18.         {
    19.             fixedGB2312Collator = new  java.text.RuleBasedCollator (
    20.                     ChineseGB2312Collator.getGB2312SpecialChars() +
    21.                     GB2312Chars
    22.                     );
    23.         }catch (ParseException  e)
    24.         {
    25.             e.printStackTrace();
    26.         }
    27.         return  fixedGB2312Collator;
    28.     }
    29.     
    30.     /**
    31.      * @return the special characters in GB2312 charset.
    32.      * 
    33.      */
    34.     public  static  final  String  getGB2312SpecialChars()
    35.     {
    36.         RuleBasedCollator  zh_CNCollator = (RuleBasedCollator )Collator .getInstance(Locale .CHINA);
    37.         //index 2125 is the last symbol "╋"
    38.         return  zh_CNCollator.getRules().substring(0,2125);
    39.     }
    40.     
    41.     /**
    42.      * 6763 Chinese characters in GB2312 charset
    43.      */
    44.     public  static  final  String  GB2312Chars =
    45.         "<吖<阿<啊< 锕<嗄<哎<哀<唉<埃<挨<锿<捱<皑<癌<嗳<矮<蔼< 霭<艾<爱<砹<隘<嗌<嫒<碍<暧<瑷<安<桉<氨<庵< 谙<鹌<鞍<俺<埯<铵<揞<犴<岸<按<案<胺<暗<黯< 肮<昂<盎<凹<坳<敖<嗷<廒<獒<遨<熬<翱<聱<螯< 鳌<鏖<拗<袄<媪<岙<傲<奥<骜<澳<懊<鏊"  +
    46.         "<八<巴<叭< 扒<吧<岜<芭<疤<捌<笆<粑<拔<茇<菝<跋<魃<把< 钯<靶<坝<爸<罢<鲅<霸<灞<掰<白<百<佰<柏<捭< 摆<呗<败<拜<稗<扳<班<般<颁<斑<搬<瘢<癍<阪< 坂<板<版<钣<舨<办<半<伴<扮<拌<绊<瓣<邦<帮< 梆<浜<绑<榜<膀<蚌<傍<棒<谤<蒡<磅<镑<勹<包< 孢<苞<胞<煲<龅<褒<雹<宝<饱<保<鸨<堡<葆<褓< 报<抱<豹<趵<鲍<暴<爆<陂<卑<杯<悲<碑<鹎<北< 贝<狈<邶<备<背<钡<倍<悖<被<惫<焙<辈<碚<蓓< 褙<鞴<鐾<奔<贲<锛<本<苯<畚<坌<笨<崩<绷<嘣< 甭<泵<迸<甏<蹦<逼<荸<鼻<匕<比<吡<妣<彼<秕< 俾<笔<舭<鄙<币<必<毕<闭<庇<畀<哔<毖<荜<陛< 毙<狴<铋<婢<庳<敝<萆<弼<愎<筚<滗<痹<蓖<裨< 跸<辟<弊<碧<箅<蔽<壁<嬖<篦<薜<避<濞<臂<髀< 璧<襞<边<砭<笾<编<煸<蝙<鳊<鞭<贬<扁<窆<匾< 碥<褊<卞<弁<忭<汴<苄<拚<便<变<缏<遍<辨<辩< 辫<灬<杓<彪<标<飑<髟<骠<膘<瘭<镖<飙<飚<镳< 表<婊<裱<鳔<憋<鳖<别<蹩<瘪<宾<彬<傧<斌<滨< 缤<槟<镔<濒<豳<摈<殡<膑<髌<鬓<冫<冰<兵<丙< 邴<秉<柄<炳<饼<禀<并<病<摒<拨<波<玻<剥<钵< 饽<啵<脖<菠<播<伯<孛<驳<帛<泊<勃<亳<钹<铂< 舶<博<渤<鹁<搏<箔<膊<踣<薄<礴<跛<簸<擘<檗< 逋<钸<晡<醭<卜<卟<补<哺<捕<不<布<步<怖<钚< 部<埠<瓿<簿"  ;
    1. }
    2. package  sorting;
    3. import  java.util.*;
    4. import  java.text.*;
    5. /**
    6.  * @author GaoJianMin
    7.  *
    8.  */
    9. public  class  ChineseGB2312Comparator implements  Comparator <String >, Comparable <String > {
    10.     private  RuleBasedCollator  GB2312Collator =
    11.         ChineseGB2312Collator.getFixedGB2312Collator();
    12.     private  String  str1;
    13.     
    14.     /**
    15.      * @param str1
    16.      */
    17.     public  ChineseGB2312Comparator(String  str1) {
    18.         this .str1 = str1;
    19.     }
    20.     /**
    21.      * 
    22.      */
    23.     public  ChineseGB2312Comparator() {
    24.         this .str1="" ;
    25.     }
    26.     /**
    27.      * @param str1
    28.      * @param str2
    29.      * @return an integer indicatint the comparison result
    30.      * @see java.util.Comparator#compare(Object, Object)
    31.      */
    32.     public  int  compare(String  str1, String  str2) {
    33.         return  GB2312Collator.compare(str1, str2);
    34.     }
    35.     /**
    36.      * @param str2
    37.      * @return an integer indicatint the comparison result
    38.      *  @see java.lang.Comparable#compareTo(Object)
    39.      */
    40.     public  int  compareTo(String  str2) {
    41.         return  GB2312Collator.compare(str1, str2);
    42.     }
    43. }


    测试代码及结果


    代码:
    1. import  java.util.*;
    2. import  java.text.*;
    3. public  class  Test
    4. {
    5.         String  [] test = new  String [] {
    6.                 "作业" ,
    7.                 "测试" ,
    8.                 "test" ,
    9.                 "我们" ,
    10.                 "。空" ,
    11.                 "镂空" ,
    12.                 "[" ,
    13.                 "浏" ,
    14.                 "皙"
    15.         };
    16.       java.util.Arrays .sort(test, new  ChineseGB2312Comparator());
    17.       System .out.println("============" );
    18.       for (String  key : test)
    19.           System .out.println(key);
    20. }


    ChineseGB2312Comparator 类同时实现了 Comparator, Comparable 接口,这样以后能够使用 compare, compareTo 方法的时候都可以使用这个类。
     
     
    二、VC++比较汉字
     
    [别名]
    CompareStringA
    [说明]
    根据用于特定“地方”环境的文本对比设置,对两个字串进行比较
    [参数表]
    LocaleLong,比较进行时的一个“地方”标识符
    dwCmpFlagsLong,带 NORM_??? 前缀的一个或多个常数,它们定义了象“忽略大小写”这样的一些选项
    lpString1String,要比较的第一个字串
    cchCount1Long,以字节为单位指定字串长度(如果是DBCS字串,则没有字符)。如设为-1,表示进行自动计算(以NULL中止字符为准)
    lpString2String,要比较的第二个字串
    cchCount2Long,第二个字串的长度(参考 cchCount1 参数说明)
    [返回值]
    Long,如lpString1<lpString2,返回1;如相等,返回2;如lpString1>lpString2,则返回3。会设置GetLastError
    [其它]
    这个函数进行的比较要以特定的语言环境为基础,并不严格按照字符值进行比较
  • 相关阅读:
    vue教程2-06 过滤器
    vue教程2-05 v-for循环 重复数据无法添加问题 加track-by='索引'
    vue教程2-04 vue实例简单方法
    Linux文件I/O
    Linux内存管理
    进程中内存地址空间的划分
    Ubuntu12.04 15.04禁止移动介质自动播放
    条件编译,头文件,静态库,共享库与多文件编程
    C语言的函数
    C语言流程控制
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318351.html
Copyright © 2011-2022 走看看