Java 8,742字节
如果不计算类定义,则可以再减少3个字节来命名函数,s
而不是减少sort
16个字节。
public class H{String d="cs|dzs?|gy|ly|sz|ty|zs";void sort(java.util.List<String>l){l.sort((a,b)->{String o="-a-á-b-cs-dzs-e-é-f-gy-h-i-í-j-k-ly-m-ny-o-ó-ö-ő-p-q-r-sz-ty-u-ú-ü-ű-v-w-x-y-zs-";int i=c(r(a),r(b),r(o));return i!=0?i:(i=c(a,b,o))!=0?i:b.charAt(0)-a.charAt(0);});}String r(String a){for(int i=0;i<8;i++)a=a.toLowerCase().replace("ááéíóőúű".charAt(i),"aaeioöuü".charAt(i));return a;}int c(String a,String b,String o){a=n(a);b=n(b);while(!"".equals(a+b)){int i=p(a,o),j=p(b,o);if(i!=j)return i-j;a=a.substring(i%4);b=b.substring(j%4);}return 0;}int p(String a,String o){a=(a+1).replaceAll("("+d+"|.).*","-$1");return o.indexOf(a)*4+a.length()-1;}String n(String a){return a.toLowerCase().replaceAll("(.)(?=\\1)("+d+")| |-","$2$2");}}
可以这样使用:
new H().sort(list);
测试套件:
public static void main(String[] args) {
test(Arrays.asList("cudar", "cukor", "cuppant", "csalit", "csata"));
test(Arrays.asList("kasza", "kaszinó", "kassza", "kaszt", "nagy", "naggyá", "nagygyakorlat", "naggyal",
"nagyít"));
test(Arrays.asList("jácint", "Jácint", "Zoltán", "zongora"));
test(Arrays.asList("Eger", "egér", "író", "iroda", "irónia", "kerek", "kerék", "kérek", "szúr", "szül"));
test(Arrays.asList("márvány", "márványkő", "márvány sírkő", "Márvány-tenger", "márványtömb"));
}
private static void test(final List<String> input) {
final ArrayList<String> random = randomize(input);
System.out.print(input + " -> " + random);
new H().sort(random);
System.out.println(" -> " + random + " -> " + input.equals(random));
}
private static ArrayList<String> randomize(final List<String> input) {
final ArrayList<String> temp = new ArrayList<>(input);
final ArrayList<String> randomOrder = new ArrayList<>(input.size());
final Random r = new Random();
for (int i = 0; i < input.size(); i++) {
randomOrder.add(temp.remove(r.nextInt(temp.size())));
}
return randomOrder;
}
屈服
[cudar, cukor, cuppant, csalit, csata] -> [csata, cudar, cuppant, csalit, cukor] -> [cudar, cukor, cuppant, csalit, csata] -> true
[kasza, kaszinó, kassza, kaszt, nagy, naggyá, nagygyakorlat, naggyal, nagyít] -> [naggyá, kassza, kaszinó, nagygyakorlat, nagyít, nagy, kaszt, kasza, naggyal] -> [kasza, kaszinó, kassza, kaszt, nagy, naggyá, nagygyakorlat, naggyal, nagyít] -> true
[jácint, Jácint, Zoltán, zongora] -> [Zoltán, jácint, zongora, Jácint] -> [jácint, Jácint, Zoltán, zongora] -> true
[Eger, egér, író, iroda, irónia, kerek, kerék, kérek, szúr, szül] -> [egér, Eger, kerék, iroda, író, kerek, kérek, szúr, irónia, szül] -> [Eger, egér, író, iroda, irónia, kerek, kerék, kérek, szúr, szül] -> true
[márvány, márványkő, márvány sírkő, Márvány-tenger, márványtömb] -> [márványtömb, márványkő, Márvány-tenger, márvány sírkő, márvány] -> [márvány, márványkő, márvány sírkő, Márvány-tenger, márványtömb] -> true
取消高尔夫:
public class HungarianOrder {
String d = "cs|dzs?|gy|ly|sz|ty|zs";
void sort(java.util.List<String> l) {
l.sort((a, b) -> {
String o = "-a-á-b-cs-dzs-e-é-f-gy-h-i-í-j-k-ly-m-ny-o-ó-ö-ő-p-q-r-sz-ty-u-ú-ü-ű-v-w-x-y-zs-";
int i = c(r(a), r(b), r(o));
return i != 0 ? i
: (i = c(a, b, o)) != 0 ? i
: b.charAt(0) - a.charAt(0);
});
}
// toLower + remove long accent
String r(String a) {
for (int i = 0; i < 8; i++)
a = a.toLowerCase().replace("ááéíóőúű".charAt(i), "aaeioöuü".charAt(i));
return a;
}
// iterate over a and b comparing positions of chars in o
int c(String a, String b, String o) {
a = n(a);
b = n(b);
while (!"".equals(a + b)) {
int i = p(a, o), j = p(b, o);
if (i != j)
return i - j;
a = a.substring(i % 4);
b = b.substring(j % 4);
}
return 0;
}
// find index in o, then looking if following characters match
// return is index * 4 + length of match; if String is empty or first character is unknown -1 is returned
int p(String a, String o) {
a = (a+1).replaceAll("("+d+"|.).*", "-$1");
return o.indexOf(a) * 4 + a.length() - 1;
}
// expand ddz -> dzdz and such
String n(String a) {
return a.toLowerCase().replaceAll("(.)(?=\\1)("+ d +")| |-", "$2$2");
}
}
我正在使用Java的List
-type和order()
-function,但是比较器都是我的。