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

13

我目前正在处理一些匈牙利语的数据。我需要对一组匈牙利语字符串进行排序。

根据此排序序列页面的说明:

匈牙利字母顺序为: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=Á,...),所以在结果中,您可以使用排序器得到以下结果:

Abdffg
Ádsdfgsd
Aegfghhrf

到目前为止,没有问题 :)

但现在,我需要按匈牙利字母表排序

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被认为与Á不同

使用CollatorStrength进行操作无法改变输出顺序。 A和Á仍然混淆。

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

到目前为止我所做的是:

  • 使用Collator进行排序,以便正确排序C / Cs,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;
          }
      });

感谢您的输入


我明白你不是在寻找“完全相同”的比较强度(Collator.IDENTICAL),对吗?那么我猜 A 和 Á 会有所不同... - helios
将强度更改为“IDENTICAL”仍会像A和Á相同一样对列表进行排序。 - ccheneson
在Java 6中,当我调用Collections.sort(words)时,它会根据您的需求对它们进行排序,例如先是A,然后是Á... - maerics
如果您添加以字母“Z”开头的单词,顺序将变为A->Z->Á,但我希望它是A->Á->Z。抱歉,我会在示例中添加更多单词。 - ccheneson
我可能来晚了,但我觉得有必要指出匈牙利字母顺序比那复杂得多。例如,这个页面上的答案都没有处理双重连字(例如,“ccs”被处理为“cs”+“cs”)。这里是规则的简短摘要。即使是这个摘要也是简化的,因为你需要一个词汇表来正确排序匈牙利单词,因为在某些特殊情况下,排序取决于单词的含义 - vsz
4个回答

9
我发现一个好主意,你可以使用RuleBasedCollator。
来源: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
谢谢,@T-Gergely。问题已经解决了。 - lsolova
1
注意:您需要注意双重二合字母。如果二合字母是双重的,则只有第一个“字母”是双重的。因此,ccs按字母顺序为cs + cs,而ssz按字母顺序为sz + sz。 - Ṃųỻịgǻňạcểơửṩ

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());
}

1

这些解决方案中是否有任何一个会将字符串(名称)“Czár”和“Csóka”排序为Czár,Csóka? 这将是正确的顺序,因为Csóka中的CS被认为是一个字母,并且在C之后。 然而,即使有所有匈牙利单词的列表,也无法识别双字符辅音,因为有时可能存在两个单词的字符完全相同,但其中一个有两个连续的辅音,而在另一个中,则有两个表示同一字母的字符。


0

改变你的映射顺序。

将数字表示作为键,字母作为值。这样可以使用TreeMap,它将按键排序。

然后你只需要执行map.get(1),它将返回字母表中的第一个字母。


我应该用哪个元素来映射这个键呢?你能给一个例子吗?-谢谢 - ccheneson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接