按匈牙利语字母顺序对匈牙利语字符串列表进行排序

Posted

技术标签:

【中文标题】按匈牙利语字母顺序对匈牙利语字符串列表进行排序【英文标题】:Sort a list of hungarian strings in the hungarian alphabetical order 【发布时间】:2011-11-22 02:11:22 【问题描述】:

我目前正在处理匈牙利语的一些数据。 我必须对匈牙利字符串列表进行排序。

根据this Collation Sequence page

匈牙利字母顺序为:A=Á, B, C, CS, D, DZ, DZS, E=É, F, G, GY、H、I=Í、J、K、L、LY、M、N、NY、O=Ó、Ö=Ő、P、Q、R、S、SZ、T、TY、 U=Ú, Ü=Ű, V, W, X, Y, Z, ZS

因此元音被视为相同 (A=Á, ...),因此您可以使用 Collator 获得类似的结果:

Abdffg
Ádsdfgsd
Aegfghhrf

到这里,没问题:)

但是现在,我有要求按照Hungarian alphabet排序

A Á B C Cs D Dz Dzs E É F G Gy H I Í J K L Ly M N Ny O Ó Ö Ő P (Q) R S Sz T Ty U Ú Ü Ű V (W) (X) (Y) Z Zs

A 被认为与 Á 不同

使用来自Collator 的Strength 不会改变输出中的顺序。 A 和 Á 还是混在一起了。

是否有任何库/技巧可以根据匈牙利字母顺序对字符串列表进行排序?

到目前为止,我正在做的是:

使用Collator 排序,以便正确排序 C/C、D、DZ、DZS... 通过基于地图比较每个单词的第一个字符再次排序

这任务看起来太麻烦了吧?

List<String> words = Arrays.asList(
        "Árfolyam", "Az",
        "Állásajánlatok","Adminisztráció",
        "Zsfgsdgsdfg", "Qdfasfas"

);

final Map<String, Integer> map = new HashMap<String, Integer>();
      map.put("A",0);
      map.put("Á",1);
      map.put("E",2);
      map.put("É",3);

      map.put("O",4);
      map.put("Ó",5);
      map.put("Ö",6);
      map.put("Ő",7);

      map.put("U",8);
      map.put("Ú",9);
      map.put("Ü",10);
      map.put("Ű",11);


      final Collator c = Collator.getInstance(new Locale("hu"));
      c.setStrength(Collator.TERTIARY);
      Collections.sort(words, c);

      Collections.sort(words, new Comparator<String>()
          public int compare(String s1, String s2) 

              int f = c.compare(s1,s2);
              if (f == 0) return 0;

              String a = Character.toString(s1.charAt(0));
              String b = Character.toString(s2.charAt(0));

              if (map.get(a) != null && map.get(b) != null) 
                  if (map.get(a) < map.get(b)) 
                      return -1;
                  
                  else if (map.get(a) == map.get(b)) 
                      return 0;
                  
                  else 
                      return 1;
                  
              


              return 0;
          
      );

感谢您的意见

【问题讨论】:

我知道您不是在寻找“相同”的比较强度 (Collat​​or.IDENTICAL),对吧?在那种情况下,我猜 A 和 Á 会有所不同...... 将强度更改为 IDENTICAL 仍然像 A 和 Á 一样对列表进行排序。 在 java 6 中,当我调用 Collections.sort(words) 时,它会根据您的需要使用 A 然后 Á... @maerics。如果你添加一个以'Z'开头的单词,顺序是A->Z->Á,我希望它是A->Á->Z。对不起,我会在示例中添加更多单词 我可能会非常非常迟到,但我觉得有必要指出匈牙利的字母顺序比这要复杂得多。例如,此页面上的答案均不处理双有向字母(“ccs”被处理为“cs”+“cs”)。 Here is 规则的简短摘要。甚至该摘要也被简化了,因为您需要一个词汇表来正确排序匈牙利语单词,因为在某些特殊情况下,排序取决于单词的含义 【参考方案1】:

我找到了一个好主意,您可以使用 RuleBasedCollat​​or。

来源:http://download.oracle.com/javase/tutorial/i18n/text/rule.html

这是匈牙利的规则:

 < a,A < á,Á < b,B < c,C < cs,Cs,CS < d,D < dz,Dz,DZ < dzs,Dzs,DZS 
 < e,E < é,É < f,F < g,G < gy,Gy,GY < h,H < i,I < í,Í < j,J
 < k,K < l,L < ly,Ly,LY < m,M < n,N < ny,Ny,NY < o,O < ó,Ó 
 < ö,Ö < ő,Ő < p,P < q,Q < r,R < s,S < sz,Sz,SZ < t,T 
 < ty,Ty,TY < u,U < ú,Ú < ü,Ü < ű,Ű < v,V < w,W < x,X < y,Y < z,Z < zs,Zs,ZS

【讨论】:

请注意,如果您也添加了多字符字母的大写版本(例如,cs、Cs、CS),它只会与大写字符串一起正常工作。 谢谢,@T-Gergely。它是固定的。 注意:你需要注意双合字母。如果一个有向图被加倍,只有第一个“字母”被加倍。因此,ccs 按字母顺序为 cs + cs,ssz 按字母顺序为 sz + sz。【参考方案2】:

您可以按流排序如下:

public List<String> sortBy(List<String> sortable) 

  Collator coll = Collator.getInstance(new Locale("hu","HU"));

  return sortable.stream()
                 .sorted(Comparator.comparing(s -> s, coll))
                 .collect(Collectors.toList());

【讨论】:

【参考方案3】:

任何解决方案都会导致将字符串(名称)“Czár”和“Csóka”排序为 Czár, Csóka?这将是正确的顺序,因为 Csóka 中的 CS 被认为是一个字母并且在 C 之后。 但是,即使使用所有匈牙利语单词的列表,也无法识别双字符辅音,因为可能存在这样的情况,两个单词可能逐个字符看起来完全相同,但一个有两个辅音在一起,而另一个有是两个字符在同一个地方代表一个字母。

【讨论】:

【参考方案4】:

更改地图的顺序。

将数字表示作为键,将字母作为值。这将允许您使用将按键排序的 TreeMap。

然后您可以执行 map.get(1),它会返回字母表的第一个字母。

【讨论】:

我会将键映射到什么元素?你能举个例子吗? -谢谢

以上是关于按匈牙利语字母顺序对匈牙利语字符串列表进行排序的主要内容,如果未能解决你的问题,请参考以下文章

如何按字典顺序对 ArrayList 进行排序?

结合字母顺序和自然顺序(又名。用户理智排序)

按字母顺序排序列表

在Python中对字符串列表进行排序[重复]

首先按频率对字符串中的字符进行排序,然后按字母顺序排序

按字母顺序对 c 字符串数组进行排序