質問は、辞書式照合順序で負の整数を処理する方法を示していません。前述の文字列ベースのメソッドは通常、負の値を先頭に並べ替えます。たとえば、{ -123, -345, 0, 234, 78 } はこの順序で残されます。ただし、マイナス記号を無視する場合、出力順序は { 0, -123, 234, -345, 78 } になります。文字列ベースのメソッドを適応させて、やや面倒な追加テストによってその順序を生成することができます。
理論的にもコード的にも、2 つの整数の常用対数の小数部分を比較するコンパレータを使用する方が簡単な場合があります。つまり、2 つの数値の 10 を底とする対数の仮数を比較します。対数ベースのコンパレータは、CPU の浮動小数点のパフォーマンス仕様と実装の品質に応じて、文字列ベースのコンパレータよりも高速または低速で実行されます。
この回答の最後に示されている Java コードには、2 つの対数ベースのコンパレータが含まれています: alogCompare
とslogCompare
. 前者は符号を無視するため、{ -123, -345, 0, 234, 78 } から { 0, -123, 234, -345, 78 } を生成します。
次に示す数値グループは、Java プログラムによって生成された出力です。
「dar rand」セクションには、dar
生成されたランダム データ配列が表示されます。1 行あたり 5 要素ずつ、横方向に読み取り、次に下方向に読み取ります。配列sar
、lara
、およびlars
最初は のソートされていないコピーであることに注意してくださいdar
。
「dar sort」セクションはdar
、 によるソート後Arrays.sort(dar);
です。
「sar lex」セクションは、でsar
ソートした後の配列を示しています。これは、Jason Cohen の回答に示されているものと似ています。Arrays.sort(sar,lexCompare);
lexCompare
Comparator
「lar s log」セクションはlars
、 でソートした後の配列を示しArrays.sort(lars,slogCompare);
ており、do と同じ順序を与える対数ベースの方法lexCompare
や、他の文字列ベースの方法を示しています。
「lar a log」セクションは、マイナス記号を無視する対数ベースの方法を示す、 でlara
ソートした後の配列を示しています。Arrays.sort(lara,alogCompare);
dar rand -335768 115776 -9576 185484 81528
dar rand 79300 0 3128 4095 -69377
dar rand -67584 9900 -50568 -162792 70992
dar sort -335768 -162792 -69377 -67584 -50568
dar sort -9576 0 3128 4095 9900
dar sort 70992 79300 81528 115776 185484
sar lex -162792 -335768 -50568 -67584 -69377
sar lex -9576 0 115776 185484 3128
sar lex 4095 70992 79300 81528 9900
lar s log -162792 -335768 -50568 -67584 -69377
lar s log -9576 0 115776 185484 3128
lar s log 4095 70992 79300 81528 9900
lar a log 0 115776 -162792 185484 3128
lar a log -335768 4095 -50568 -67584 -69377
lar a log 70992 79300 81528 -9576 9900
Java コードを以下に示します。
// Code for "How can I sort numbers lexicographically?" - jw - 2 Jul 2014
import java.util.Random;
import java.util.Comparator;
import java.lang.Math;
import java.util.Arrays;
public class lex882954 {
// Comparator from Jason Cohen's answer
public static Comparator<Integer> lexCompare = new Comparator<Integer>(){
public int compare( Integer x, Integer y ) {
return x.toString().compareTo( y.toString() );
}
};
// Comparator that uses "abs." logarithms of numbers instead of strings
public static Comparator<Integer> alogCompare = new Comparator<Integer>(){
public int compare( Integer x, Integer y ) {
Double xl = (x==0)? 0 : Math.log10(Math.abs(x));
Double yl = (y==0)? 0 : Math.log10(Math.abs(y));
Double xf=xl-xl.intValue();
return xf.compareTo(yl-yl.intValue());
}
};
// Comparator that uses "signed" logarithms of numbers instead of strings
public static Comparator<Integer> slogCompare = new Comparator<Integer>(){
public int compare( Integer x, Integer y ) {
Double xl = (x==0)? 0 : Math.log10(Math.abs(x));
Double yl = (y==0)? 0 : Math.log10(Math.abs(y));
Double xf=xl-xl.intValue()+Integer.signum(x);
return xf.compareTo(yl-yl.intValue()+Integer.signum(y));
}
};
// Print array before or after sorting
public static void printArr(Integer[] ar, int asize, String aname) {
int j;
for(j=0; j < asize; ++j) {
if (j%5==0)
System.out.printf("%n%8s ", aname);
System.out.printf(" %9d", ar[j]);
}
System.out.println();
}
// Main Program -- to test comparators
public static void main(String[] args) {
int j, dasize=15, hir=99;
Random rnd = new Random(12345);
Integer[] dar = new Integer[dasize];
Integer[] sar = new Integer[dasize];
Integer[] lara = new Integer[dasize];
Integer[] lars = new Integer[dasize];
for(j=0; j < dasize; ++j) {
lara[j] = lars[j] = sar[j] = dar[j] = rnd.nextInt(hir) *
rnd.nextInt(hir) * (rnd.nextInt(hir)-44);
}
printArr(dar, dasize, "dar rand");
Arrays.sort(dar);
printArr(dar, dasize, "dar sort");
Arrays.sort(sar, lexCompare);
printArr(sar, dasize, "sar lex");
Arrays.sort(lars, slogCompare);
printArr(lars, dasize, "lar s log");
Arrays.sort(lara, alogCompare);
printArr(lara, dasize, "lar a log");
}
}