2015-04-03 7 views
6

Ich weiß, dass die Ergebnisse für string1.compareTo (string2) eine Zahl -1 oder darunter sein wird, wenn string2 alphabetisch vor string1 kommt und eine Zahl 1 oder höher, wenn die andere Richtung unterschiedlich ist. Ich muss nur -1, 0 oder 1 zurückgeben.Wie kann ich die Ergebnisse von String.compareTo() am besten auf -1, 0 und 1 beschränken?

Ich kann es auf eine scheinbar klobige Art und Weise kodieren, aber ich habe das Gefühl, dass es eine effizientere/elegantere Methode dafür geben muss. Jede Hilfe wäre willkommen!

String s1 = "aardvark"; 
String s2 = "zebra"; 
int c = s1.compareTo(s2); // -25 
if (c > 0) { 
    c = 1; 
} else if (c < 0) { 
    c = -1; 
} 

Gibt es irgendeine Art von mathematischen Operation, die alle positiven ganzen Zahlen auf 1 ändert und alle negativen ganzen Zahlen auf -1?


EDIT: Ich muss sagen, ich bin nur dankbar eine Frage gestellt zu haben, die nicht downvoted und gelöscht, aber die schnelle und intelligente Antworten sind wunderbar. Hier sind die Antworten, die ich bisher getestet habe. Ich wollte meine Ergebnisse mit denen teilen, die später kommen.

Mein Testcode: (läuft jede Lösung etwa 2600 mal bei verschiedenen Werten)

String s1 = ""; 
String s2 = "m"; 
for (int i = 0; i < 100; i++) { 
    for (char j = 'a'; j < 'z'; j++) { 
     s2 = ("" + j); 
     solution1(s1.compareTo(s2)); 
    } 
} 

Mein ursprünglicher Code: ~ 1,5 ms

if (c > 0) { 
    c = 1; 
} else if (c < 0) { 
    c = -1; 
} 

Lösung 1: ~ 4 ms

c = (int) Math.signum(c); 

Lösung 2: ~ 2ms

c = c > 0 ? 1 : c < 0 ? -1 : 0; 

Lösung 3: ~ 2 ms

c = Math.max(-1, Math.min(1, c)); 

Lösung 4: ~ 2 ms

c = Integer.compare(c, 0); 

Ich mag sie alle besser als meine ursprüngliche, so danke Ihnen allen gemeinsam. Lösung 4 erhält aufgrund von Geschwindigkeit und Lesbarkeit das Häkchen, also danke besonders.

+1

Es gibt 'Math.signum' aber es dauert nur ein' float' oder 'double'; Verwenden Sie es und werfen Sie Ihre 'int' und das Ergebnis wird nicht effizienter als das, was Sie bereits tun. – Jesper

+0

Nun, es gibt keinen kürzeren Weg, das zu tun, während das Gerät vergleichbar ist. Verwenden Sie möglicherweise müssen Sie Ihre String-Klasse überschreiben und zeigen, was genau ist eine größere Zeichenfolge? Ist es Länge? Ist die alphabetische Reihenfolge? Bei vergleichbarer Maschine erhalten Sie einen Wert kleiner/größer als Null. –

+0

@Barak Kedem: String ist eine letzte Klasse. Viel Glück versuchen, es zu überschreiben – Stultuske

Antwort

4

Es ist eigentlich ganz einfach:

return Integer.compare(s1.compareTo(s2), 0); 
+0

Ich habe das überprüft, um sicherzustellen, dass es funktioniert, und es tut. Obwohl die Dokumentation nur sagt, dass es eine "positive Zahl" oder "negative Zahl" als Ausgabe gibt, scheint es immer -1, 0 oder 1 zu sein. Jeder Haken mit dieser Methode, der ein unerwartetes Ergebnis verursachen würde? – randomraccoon

+0

Nein, wenn Sie den Quellcode überprüfen, es sagt nur 'zurück nach links richtig? 1: 0; ' –

+0

Super, danke! – randomraccoon

3

Der ternäre Operator wäre kompakter:

c = c>0?1:c<0?-1:0; 

Math.signum kann auch verwendet werden, aber eine Besetzung in int benötigen:

c = (int)Math.signum(c); 
2

Math.signum() bietet, was man sich wünschen:

Gibt die Signum-Funktion des Arguments zurück; Null, wenn das Argument Null ist, 1,0, wenn das Argument größer als Null ist, -1,0, wenn das Argument kleiner als Null ist.

+0

Aber es dauert ein 'float' oder' double' - Casting the ' int ',' float' oder 'double', und das Ergebnis von' signum' zurück zu 'int' macht es nicht effizienter. – Jesper

+0

Es ist elegant, was Sie verlangen. Ist es effizient? Also also. – mtyurt

+0

Aber nicht effizient. Wenn Sie sich den Quellcode von 'Math.signum' im JDK anschauen, werden Sie sehen, dass es komplizierter ist als das, was randomraccoon bereits macht. – Jesper

2

Sie könnten den Wertebereich mit min und max. Das ist eine nützliche Methode manchmal, so dass Sie es als Utility-Methode verwenden:

String s1 = "aardvark"; 
String s2 = "zebra"; 
int c = s1.compareTo(s2); // -25 
return clamp(c, -1, 1); 

Mit

int clamp(int value, int min, int max) { 
    return Math.max(min, Math.min(max, value)); 
} 

Mehr elegant?So würde ich sagen. Effizienter? Wahrscheinlich nicht.

Verwandte Themen