私はバブルソートアルゴリズムを実装していて、パラメータの両方を受け入れることができるようにしたいと思っていInteger
ますString
。すべての入力を文字列としてキャストし、このcompareTo
メソッドを使用して、文字列としてキャストされた整数を文字列と比較します。compareTo
キャストされた整数を比較するために使用すると、間違った答えが返されます。私は何が間違っているのですか?
7 に答える
Integer.compareToは、数値を数値でソートします。これはあなたが望むものです。
String.compareToは、文字列を辞書式に並べ替えます。つまり、アルファベット順です。
Windows 3.1で、デジタルカメラの写真のフォルダがPHOTO1、PHOTO10、PHOTO100、PHOTO2、PHOTO20、PHOTO3などのように注文されたことを覚えています。Windows XPは、予想どおりにそれらを並べ替えます:PHOTO1、PHOTO2、PHOTO3など。これは、数値を表す文字列に対して特別な並べ替え規則があるためです。
辞書式順序では、1つの文字列Aの各文字が、別の文字列Bの対応する文字と比較されます。2つの文字列の対応する文字ごとに、次のようになります。
- Aの現在の文字が辞書式順序でBの文字よりも小さい(アルファベットの前に来る)場合、AはBの前に来ます。
- Bの文字がAの文字よりも小さい場合、BはAの前に来ます。
- 2つのキャラクターが同じである場合、まだわかりません。次のものがチェックされます。
- 文字列の1つに文字が残っていない場合は、短い方の文字が長い方の文字の前に来ます。
- 両方の文字列に文字が残っていない場合、それらは同じ文字列です。
ここでの4番目のポイントは、Eddieによる問題の分析が正しいと仮定して、間違った答えが得られる理由です。
文字列「10」と「2」について考えてみます。辞書式順序では、それぞれの最初の文字である「1」と「2」がそれぞれ見られます。Javaが使用する文字セットでは、文字「1」が「2」の前に来るため、「b」が「 h'。
並べ替える前に、文字列を整数にキャストすることをお勧めします。これを行うには、Integer.parseStringを使用します。
同じリストに整数と文字列を混在させてもよろしいですか?もしそうなら、整数は文字列よりも小さいですか、それとも大きいですか?この特定のソート基準は何ですか?
整数の個別のリストと文字列のリスト(および他のクラスのリスト)をソートするバブルソートメソッドを作成することもできます。そのためには、ジェネリックを使用できます。例えば:
public static <T> void bubbleSort(List<T> elements, Comparator<T> comparator) {
// your implementation
}
パラメータを使用してcomparator
を比較しますelements
。そのため、整数または文字列(両方を同時に使用することはできません)にすることができます。コンパイラは、[警告なしに]あるクラスのオブジェクトのリストと別のクラスのコンパレータを渡すことを許可しないため、比較は常に機能します。
のインスタンスを取りますComparable
。
文字列を実際に整数にキャストすることはできず、comparryoメソッドはありません。
あなたが説明することは実際には不可能です...それでおそらくあなたはコードを投稿する必要があります。これがあなたがしていることの私の解釈です:
public int compareTo(final Object o)
{
final String str;
str = (String)o; // this will crash if you pass it an Integer.
// rest of the code.
}
compareToのドキュメントはここにあります、あなたは本当に契約に従うべきです。
まず、Comparatorは2つのオブジェクトを取得するのに対し、Comparableは現在のオブジェクトを渡されたオブジェクトと比較し、StringまたはIntegerのcompareTo()メソッドを変更できないため、ComparatorをComparableにしないようにします。
public class CompareIntegersAsStrings implements Comparator {
public int compare(Object o1, Object o2) {
return o1.toString().compareTo(o2.toString());
}
}
あなたが本当に意味しているのは、整数を文字列に変換してから比較しているということだと仮定すると、これは機能しません。たとえば、整数1234
と整数1
と整数があるとし2
ます。これらを文字列に変換して比較すると、次の順序になります。
1
1234
2
これはASCIIソートには正しく、数値ソートには正しくありません。つまり、あなたのコードは次のようなことをしていると思います。
public int myCompare(Integer a1, Integer a2) {
myCompare(String.valueOf(a1), String.valueOf(a2));
}
public int myCompare(String a1, String a2) {
....
}
なぜ私はこれを仮定するのですか?間違った結果を取得することについて話しているのであって、例外を取得することについて話しているのではないからです。実際に例外が発生している場合、他のポスターは正しく、キャストは機能しません。
String
これは、2つの文字列の中で最小長の文字のみが比較されるクラスの以下のJavaAPIコードが原因です。
public int compareTo(String anotherString) {
int len1 = value.length;
int len2 = anotherString.value.length;
int lim = Math.min(len1, len2); //**HERE**
char v1[] = value;
char v2[] = anotherString.value;
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return len1 - len2;
}
このAPIを使用して比較すると
String first = "ABCD";
String second = "ABZ";
System.out.println("" + "ABCD".compareTo("ABZ")); //-23
ABCDがABZ未満であることを示す負の値を返します。これは、CがZ未満であり、最初の文字列のDを無視することを意味します。
だから多分私たちは以下のようなものが必要です
class StringNumericComparator implements Comparator<String> {
@Override
public int compare(String o1, String o2) {
int len1 = o1.length();
int len2 = o2.length();
if(len1 != len2) {
return len1 - len2; //Else iterate all diff lengh chars and SUM it.
}
int lim = Math.min(len1, len2);
char v1[] = o1.toCharArray();
char v2[] = o2.toCharArray();
int k = 0;
while (k < lim) {
char c1 = v1[k];
char c2 = v2[k];
if (c1 != c2) {
return c1 - c2;
}
k++;
}
return 0;
}
}