sfu*_*ger 4 java sorting algorithm
我目前正在研究一个简单的编程问题,可能很有趣的优化 - 至少对于那些认为编程是艺术的人来说:)所以这就是:
如何在保持自然秩序的同时最好地表现长弦乐队?
此外,String表示应匹配^[A-Za-z0-9]+$.(我在这里不是太严格,但是避免使用控制字符或任何可能导致令人头疼的编码,在XML中是非法的,有换行符或类似的字符肯定会导致问题)
这是一个JUnit测试用例:
@Test
public void longConversion() {
final long[] longs = { Long.MIN_VALUE, Long.MAX_VALUE, -5664572164553633853L,
-8089688774612278460L, 7275969614015446693L, 6698053890185294393L,
734107703014507538L, -350843201400906614L, -4760869192643699168L,
-2113787362183747885L, -5933876587372268970L, -7214749093842310327L, };
// keep it reproducible
//Collections.shuffle(Arrays.asList(longs));
final String[] strings = new String[longs.length];
for (int i = 0; i < longs.length; i++) {
strings[i] = Converter.convertLong(longs[i]);
}
// Note: Comparator is not an option
Arrays.sort(longs);
Arrays.sort(strings);
final Pattern allowed = Pattern.compile("^[A-Za-z0-9]+$");
for (int i = 0; i < longs.length; i++) {
assertTrue("string: " + strings[i], allowed.matcher(strings[i]).matches());
assertEquals("string: " + strings[i], longs[i], Converter.parseLong(strings[i]));
}
}
Run Code Online (Sandbox Code Playgroud)
这是我正在寻找的方法
public static class Converter {
public static String convertLong(final long value) {
// TODO
}
public static long parseLong(final String value) {
// TODO
}
}
Run Code Online (Sandbox Code Playgroud)
我已经对如何解决这个问题有了一些想法.尽管如此,我仍然可以从社区中获得一些好的(有创意的)建议.
另外,如果这种转换会很好
编辑:我很高兴看到两个非常有信誉的程序员遇到了和我一样的问题:使用' - '表示负数不能正常工作,因为' - '不会改变排序顺序:
cle*_*tus 13
好的,拿两个:
class Converter {
public static String convertLong(final long value) {
return String.format("%016x", value - Long.MIN_VALUE);
}
public static long parseLong(final String value) {
String first = value.substring(0, 8);
String second = value.substring(8);
long temp = (Long.parseLong(first, 16) << 32) | Long.parseLong(second, 16);
return temp + Long.MIN_VALUE;
}
}
Run Code Online (Sandbox Code Playgroud)
这个需要一点解释.首先,让我证明它是可逆的,并且由此产生的转换应证明顺序:
for (long aLong : longs) {
String out = Converter.convertLong(aLong);
System.out.printf("%20d %16s %20d\n", aLong, out, Converter.parseLong(out));
}
Run Code Online (Sandbox Code Playgroud)
输出:
-9223372036854775808 0000000000000000 -9223372036854775808
9223372036854775807 ffffffffffffffff 9223372036854775807
-5664572164553633853 316365a0e7370fc3 -5664572164553633853
-8089688774612278460 0fbba6eba5c52344 -8089688774612278460
7275969614015446693 e4f96fd06fed3ea5 7275969614015446693
6698053890185294393 dcf444867aeaf239 6698053890185294393
734107703014507538 8a301311010ec412 734107703014507538
-350843201400906614 7b218df798a35c8a -350843201400906614
-4760869192643699168 3dedfeb1865f1e20 -4760869192643699168
-2113787362183747885 62aa5197ea53e6d3 -2113787362183747885
-5933876587372268970 2da6a2aeccab3256 -5933876587372268970
-7214749093842310327 1be00fecadf52b49 -7214749093842310327
Run Code Online (Sandbox Code Playgroud)
正如你所看到的Long.MIN_VALUE和Long.MAX_VALUE(前两行)是正确的,其他值基本同步下跌.
这是做什么的?
假设有符号的字节值,你有:
现在,如果您为这些值添加0x80,您将得到:
这是正确的顺序(溢出).
基本上上面是使用64位有符号长度而不是8位有符号字节.
转换回来更加迂回.您可能认为可以使用:
return Long.parseLong(value, 16);
Run Code Online (Sandbox Code Playgroud)
但你不能.将16 f传递给该函数(-1),它将抛出异常.它似乎将其视为无符号十六进制值,long无法容纳.所以我把它分成两半并解析每一块,将它们组合在一起,左移前半部分32位.
| 归档时间: |
|
| 查看次数: |
1337 次 |
| 最近记录: |