Сортировка списка венгерских строк в венгерском алфавитном порядке
Я работаю в данный момент с некоторыми данными в венгерских языках.
Мне нужно отсортировать список строк венгров.
Согласно эта страница последовательности сортировки
Венгерский алфавитный порядок: A = Á, B, C, CS, D, DZ, DZS, E = É, F, G, GY, H, я = Í, 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
До этого нет проблем:)
Но теперь у меня есть требование сортировать по венгерский алфавит
A Á B C Cs D Dz Dzs E É F G Gy H я Í J K L Ly M N Ny O Ö Ő P (Q) R S Sz T Ty U Ú Ü Ű V (W) (X) (Y) Z Zs
A считается отличным от Á
Воспроизведение с Strength из Collator
не изменяет порядок в выходе. A и Á все еще перемешиваются.
Есть ли какие-либо librairies/tricks для сортировки списка строк в соответствии с венгерским алфавитным порядком?
До сих пор я делаю:
- Сортировка с
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;
}
});
Спасибо за ваш вклад
Ответы
Ответ 1
Я нашел хорошую идею, вы можете использовать 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
Ответ 2
Измените порядок вашей карты.
Поместите числовое представление в качестве ключа и буквы в качестве значения. Это позволит вам использовать TreeMap, который будет сортироваться по ключу.
Затем вы можете просто сделать map.get(1) и вернуть первую букву алфавита.
Ответ 3
Это работает для меня (даже с ВСТРОЕННЫМ):
import static org.junit.Assert.*;
import java.text.Collator;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import org.junit.Test;
public class TestCollation {
@Test
public void testCollation () {
List<String> words = Arrays.asList(
"Árfolyam", "Az",
"Állásajánlatok","Adminisztráció",
"Zsfgsdgsdfg", "Qdfasfas"
);
final Collator c = Collator.getInstance(new Locale("hu"));
// c.setStrength(Collator.TERTIARY);
Collections.sort(words, c);
assertEquals ("Adminisztráció", words.get(0));
assertEquals ("Állásajánlatok", words.get(1));
assertEquals ("Árfolyam", words.get(2));
assertEquals ("Az", words.get(3));
assertEquals ("Qdfasfas", words.get(4));
assertEquals ("Zsfgsdgsdfg", words.get(5));
}
}
Ответ 4
Будет ли какое-либо из решений приводить к упорядочению строк (имен) "Czár" и "Csóka" как Czár, Csóka? Это будет правильный порядок, поскольку CS в Csóka считается одной буквой и находится после C.
Однако распознавание двухсимвольных согласных невозможно даже со списком всех венгерских слов, так как могут быть случаи, когда два слова могут выглядеть одинаково по характеру, но в одном есть два согласных вместе, а в другом - это два символа, представляющих одну букву в одном и том же месте.