【问题标题】:Is there any way to sort strings in all languages?有没有办法对所有语言的字符串进行排序?
【发布时间】:2011-11-29 19:38:43
【问题描述】:

我有这个代码。它在法语和俄语中正确排序。我使用了 Locale.US,它似乎是正确的。这个解决方案适用于所有语言吗?它适用于其他语言吗?例如:中文、韩文、日文……如果不是,有什么更好的解决方案?

public class CollationTest {
    public static void main(final String[] args) {
        final Collator collator = Collator.getInstance(Locale.US);
        final SortedSet<String> set = new TreeSet<String>(collator);

        set.add("abîmer");
        set.add("abîmé");
        set.add("aberrer");
        set.add("abhorrer");
        set.add("aberrance");
        set.add("abécédaire");
        set.add("abducteur");
        set.add("abdomen");

        set.add("государственно-монополистический");
        set.add("гостить");
        set.add("гостевой");
        set.add("гостеприимный");
        set.add("госпожа");
        set.add("госплан");
        set.add("господи");
        set.add("господа");

        for(final String s : set) {
            System.out.println(s);
        }
    }
}

更新: 抱歉,我不要求此集必须按顺序包含所有语言。我的意思是这个集合包含一种语言并在每种语言中正确排序。

public class CollationTest {
    public static void main(final String[] args) {
        final Collator collator = Collator.getInstance(Locale.US);
        final SortedSet<String> set = new TreeSet<String>(collator);

        // Sorting in French.
        set.clear();
        set.add("abîmer");
        set.add("abîmé");
        set.add("aberrer");
        set.add("abhorrer");
        set.add("aberrance");
        set.add("abécédaire");
        set.add("abducteur");
        set.add("abdomen");
        for(final String s : set) {
            System.out.println(s);
        }

        // Sorting in Russian.
        set.clear();
        set.add("государственно-монополистический");
        set.add("гостить");
        set.add("гостевой");
        set.add("гостеприимный");
        set.add("госпожа");
        set.add("госплан");
        set.add("господи");
        set.add("господа");
        for(final String s : set) {
            System.out.println(s);
        }
    }
}

【问题讨论】:

  • 我认为您无法有意义地定义跨语言单词的顺序。
  • 即使该集合仅包含一种语言,您仍需要在每次排序时为Collator 选择正确的Locale
  • 英语将字母的所有变体排序在该字母下,因此 Ä 和 Å 被视为 A。但在瑞典语中,Ä 和 Å 是在 Z 之后找到的唯一字母。
  • 提醒,并非所有的“亚洲语言”都是相同的。例如,韩语使用字母表(如英语)并具有明确的排序顺序。

标签: java collation string-comparison


【解决方案1】:

因为每种语言都有自己的字母顺序,所以你不能。例如,

您所说的俄语有с 字母的顺序与土耳其语不同。

您应该始终使用整理器。我可以向您建议的是我们的 Collection API。

    //
    // Define a collator for German language
    //
    Collator collator = Collator.getInstance(Locale.GERMAN);

    //
    // Sort the list using Collator
    //
    Collections.sort(words, collator);

如需进一步信息检查,请参阅here

该程序显示了当您使用两个不同的整理器对相同的单词列表进行排序时会发生什么:

整理器 fr_FRCollat​​or = Collat​​or.getInstance(new Locale("fr","FR"));

Collat​​or en_USCollat​​or = Collat​​or.getInstance(new Locale("en","US"));

排序方法称为 sortStrings,可以与任何 Collat​​or 一起使用。注意 sortStrings 方法调用了 compare 方法:

 public static void sortStrings(Collator collator, 
                           String[] words) {
  String tmp;
     for (int i = 0; i < words.length; i++) {
        for (int j = i + 1; j < words.length; j++) { 
           if (collator.compare(words[i], words[j]) > 0) {
              tmp = words[i];
              words[i] = words[j];
              words[j] = tmp;
           }
         }
      }
 }

English Collat​​or 将单词排序如下:

桃子 佩切 佩切 罪

根据法语的排序规则,前面的列表顺序错误。在法语中,péché 应该在排序列表中跟随 pêche。 French Collat​​or 对单词数组进行正确排序,如下所示:

桃子 佩切 佩切 罪

【讨论】:

    【解决方案2】:

    即使您可以准确地检测到所使用的语言,有用的排序规则通常也特定于特定语言+国家/地区的组合。即使在语言+国家/地区内,排序规则也会因使用情况或某些定制而异。

    但是,如果您确实需要对任意文本集进行排序,最好的选择是Unicode Collation Algorithm,它为任何 Unicode 文本定义了与语言无关的排序规则。该算法是可定制的,但不一定给出对任何一种文化都有意义的结果(而且绝对不能跨越它们)。

    Java 的排序规则类不实现此算法,但它作为ICU's RuleBaseCollator 的一部分提供。

    【讨论】:

    • 在 java 中,您使用 Locale("") 来获取根区域设置(在 Java 7 中有一个 Locale.ROOT 常量)。此语言环境的 Collat​​or 是 UCA。
    【解决方案3】:

    据我所知,中国人的语言没有任何顺序,日本人可能有平假名或片假名的顺序,但在汉字中是值得怀疑的。但是在计算机科学中,一切都由数字表示,语言唱歌也是如此。每个符号对应唯一的 UNICODE 编号。所以这可能是你的解决方案,使用它们的 UNICODE 位置对单词进行排序。

    【讨论】:

    • 汉字和日文汉字可以按部首和笔画数排序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-30
    • 2010-10-23
    • 2020-12-09
    • 1970-01-01
    • 2020-10-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多