2015-09-26 14 views
9

Ich schreibe eine Methode, die true zurückgibt, wenn einer der Strings am Ende des anderen Strings erscheint, und die Strings sind unterschiedlich. Wir können nicht endsWith() verwenden,Vergleichen von Teilstrings in Java

Zum Beispiel:

  • wenn a = "all" und b = "Ball", zurückkehren würde die Methode true.

  • Wenn a = "Ja" und b = "Ja", würde die Methode false zurückgeben.

Hier ist, was ich bisher habe, aber es hält String-Index außerhalb des zulässigen Bereichs zu sagen = -1

public static boolean startOther(String a, String b){ 
    if(a.equals(b)) 
     return false; 
    int pos=a.indexOf(b); 
    int pos1=b.indexOf(a); 
    int len=a.length(); 
    int len1=b.length(); 
    if(pos>-1 && a.substring(len-pos).equals(b)|| pos1>-1 && b.substring(len1-pos1).equals(a)) 
     return true; 
    return false; 
} 
+3

Hinweis: http://docs.oracle.com/javase/7/docs/api/java/lang/String. html # endsWith% 28java.lang.String% 29 –

+1

In Bezug auf den Fehler: wenn a nicht enthält b, pos ist -1, und Sie tun also astring (len + 1), die so für ein fragt Index außerhalb der Grenzen der Zeichenfolge. Ein Debugger hätte das sofort gezeigt. Sie sollten es lernen. –

Antwort

2

Es ist ein bisschen von „aussehen, bevor Sie springen“, aber was Sie wollen, ist zu tun:

  • Überprüfen Sie die Indexposition der einzelnen Strings in einem anderen.
  • Wenn (und nur wenn) die Indexposition vorhanden ist, überprüfen Sie, ob die Teilzeichenfolge von diesem Indexpunkt bis zum Ende übereinstimmt.
  • Andernfalls wird false zurückgegeben.

Wenn Sie irgendeine Art von Subtraktion durchführen, erhalten Sie nicht die richtige Größe der Teilzeichenfolge; Das heißt, wenn Sie die Länge der Zeichenfolge, die Sie überprüfen, subtrahieren, erhalten Sie nur ein Zeichen.

public static boolean startOther(String left, String right) { 
    if (left == null || right == null || left.equals(right)) { 
     return false; 
    } 
    int rightSubstringInLeft = left.indexOf(right); 
    int leftSubstringInRight = right.indexOf(left); 

    if(rightSubstringInLeft != -1) { 
     return left.substring(rightSubstringInLeft).equals(right); 
    } else if(leftSubstringInRight != -1) { 
     return right.substring(leftSubstringInRight).equals(left); 
    } else { 
     return false; 
    } 
} 

Hier ist eine optimierte Form des gleichen Codes, wie in den Kommentaren hervorgehoben. Grundsätzlich ist es das gleiche, aber Sie müssen keine weitere equals-Prüfung für die Teilzeichenfolge durchführen, da lastIndexOf Ihnen immer nur den letzten Index der gesamten Teilzeichenfolge geben würde.

public static boolean startOther(String left, String right) { 
    if (left == null || right == null || left.equals(right)) { 
     return false; 
    } 
    int rightSubstringInLeft = left.lastIndexOf(right); 
    int leftSubstringInRight = right.lastIndexOf(left); 

    if(rightSubstringInLeft != -1) { 
     return rightSubstringInLeft == left.length() - right.length(); 
    } else if(leftSubstringInRight != -1) { 
     return leftSubstringInRight == right.length() - left.length(); 
    } else { 
     return false; 
    } 
} 
+0

Das ist ziemlich ineffizient. Warum nicht a.lastIndexOf (b) verwenden und überprüfen, ob der zurückgegebene Index a.length() - b.length() ist? Oder verwenden Sie a.lastIndexOf (b, a.length() - b.length()), und überprüfen Sie, ob der zurückgegebene Wert 0 ist? Die Überprüfung auf Teilstring-Gleichheit ist redundant, da lastIndexOf() dies bereits tut. –

+0

[String # lastIndexOf] (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#lastIndexOf (int)) tut nicht das, was Sie in diesem Fall tun sollten Szenario. Es wird erwartet, dass Sie einen Unicode-Punkt an diese Methode übergeben, im Gegensatz zu einer Ganzzahl beliebiger Art. – Makoto

+0

Es gibt mehrere lastIndexOf() -Methoden: http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#lastIndexOf%28java.lang.String%29 und http: // docs .oracle.com/javase/7/docs/api/java/lang/String.html # lastIndexOf% 28java.lang.String,% 20int% 29 sind die, über die ich spreche –

1

Da Sie nicht endsWith, ersten Test für null verwenden können. Dann hol die Längen. Testen Sie, dass sie nicht gleich sind. Überprüfen Sie, ob die indexOf + -Länge für true gleich ist. So etwas wie

public static boolean startOther(String a, String b) { 
    if (a == null || b == null) return false; 
    int aLen = a.length(); 
    int bLen = b.length(); 
    if (aLen != bLen) { 
     if (aLen < bLen) { 
      int p = b.indexOf(a); 
      return p != -1 && p + aLen == bLen; 
     } else { 
      int p = a.indexOf(b); 
      return p != -1 && p + bLen == aLen; 
     } 
    } 
    return false; 
} 

, die ich wie

getestet
public static void main(String[] args) { 
    System.out.println(startOther("all", "ball")); 
    System.out.println(startOther("yes", "yes")); 
} 

und bekam die (angefragt) Ausgabe

true 
false 
+1

Oder einfach: 'return (a.length()! = B.length()) && (a.endsWith (b) || bendsWith (a))', das sollte schneller sein, da es nicht muss Auf Gleichheit prüfen. –

1
indexOf(String s) 

Returns: der Index des ersten Auftretens der angegebene Teilzeichenfolge oder -1, wenn kein solches Zeichen vorhanden ist.

Wenn indexOf() -1 zurückgegeben hat und Sie a.substring(len-pos) aufrufen, lautet der Parameter len - (-1) = len + 1. Das ist die Ursache von out of range.

Dieser Fall geschieht immer in Ihrem Code, wegen zwei Spiegelleitungen:

int pos=a.indexOf(b); 
int pos1=b.indexOf(a); 

Wenn Sie gleich vor dem Methodenaufruf überprüft, von pos immer wurde -1. Es ist offensichtlich: Wenn eine Zeichenfolge eine andere enthält und sie nicht gleich sind, dann enthält die zweite Zeichenfolge nicht zuerst.

1

Eine Kombination aus length() und regionMatches(int toffset, String other, int ooffset, int len) sollte sehr effizient sein:

public static boolean startOther(final String a, final String b) { 
    final int aLength = a.length(); 
    final int bLength = b.length(); 
    return aLength != bLength && (aLength > bLength ? a.regionMatches(aLength - bLength, b, 0, bLength) 
                : b.regionMatches(bLength - aLength, a, 0, aLength)); 
}