2015-09-26 24 views
9

Tôi đang viết một phương thức sẽ trả về true nếu một trong các chuỗi xuất hiện ở cuối cùng của chuỗi khác và các chuỗi khác nhau. Chúng tôi không thể sử dụng endsWith()So sánh các chất nền trong Java

Ví dụ:

  • nếu a = "tất cả" và b = "quả bóng", phương pháp này sẽ trở thành sự thật.

  • nếu a = "yes" và b = "yes", phương thức sẽ trả về false.

Dưới đây là những gì tôi có cho đến nay nhưng nó vẫn không ngừng nói chỉ số chuỗi ra khỏi phạm vi = -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

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

+1

Về lỗi: nếu không chứa b, pos là -1, và do đó bạn đang thực hiện a.substring (len + 1), do đó sẽ yêu cầu lập chỉ mục ngoài giới hạn của chuỗi. Một trình gỡ lỗi sẽ cho thấy ngay lập tức. Bạn nên học cách sử dụng nó. –

Trả lời

2

Đó là một chút "xem xét trước khi bạn bước nhảy vọt", nhưng những gì bạn muốn làm là:

  • Kiểm tra vị trí chỉ số của mỗi chuỗi trong vòng khác.
  • Nếu (và chỉ khi) vị trí chỉ mục tồn tại, hãy kiểm tra xem chuỗi con từ vị trí chỉ mục đó tất cả các cách đến kết thúc phù hợp với.
  • Nếu không, hãy trả về false.

Nếu bạn thực hiện bất kỳ phép trừ nào, bạn sẽ không nhận được kích thước chính xác của chuỗi con; nghĩa là, nếu bạn trừ độ dài của chuỗi bạn đang kiểm tra, bạn sẽ chỉ nhận được một ký tự.

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; 
    } 
} 

Dưới đây là hình thức được tối ưu hóa nhiều hơn của cùng một mã, như được nêu trong các nhận xét. Về cơ bản nó là như nhau, nhưng bạn không cần phải thực hiện một bằng kiểm tra trên chuỗi con, vì lastIndexOf sẽ chỉ bao giờ cung cấp cho bạn chỉ mục cuối cùng của toàn bộ chuỗi con.

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

Điều đó khá không hiệu quả. Tại sao không sử dụng a.lastIndexOf (b), và kiểm tra xem chỉ số trả về là a.length() - b.length()? Hoặc sử dụng a.lastIndexOf (b, a.length() - b.length()), và kiểm tra giá trị trả về là 0? Việc kiểm tra sự bình đẳng chuỗi con là thừa, vì lastIndexOf() đã thực hiện nó. –

+0

[String # lastIndexOf] (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#lastIndexOf (int)) không làm những gì bạn tin rằng nó sẽ làm trong kịch bản. Bạn dự kiến ​​sẽ vượt qua một điểm Unicode để phương pháp đó như trái ngược với một số nguyên của bất kỳ loại nào. – Makoto

+0

Có một số phương thức lastIndexOf(): http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#lastIndexOf%28java.lang.String%29 và http: // docs .oracle.com/javase/7/docs/api/java/lang/String.html # lastIndexOf% 28java.lang.String,% 20int% 29 là những gì tôi đang nói về –

1

Vì bạn không thể sử dụng endsWith, thử nghiệm đầu tiên cho null. Sau đó nhận được độ dài. Kiểm tra rằng chúng không giống nhau. Kiểm tra chiều dài indexOf + bằng true. Một cái gì đó như

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; 
} 

mà tôi thử nghiệm như

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

và đã nhận được (yêu cầu) đầu ra

true 
false 
+1

Hoặc đơn giản: 'return (a.length()! = B.length()) && (a.endsWith (b) || b.endsWith (a))', sẽ nhanh hơn vì nó không phải kiểm tra bình đẳng. –

1
indexOf(String s) 

Returns: chỉ số về sự xuất hiện đầu tiên của chuỗi con được chỉ định, hoặc -1 nếu không có sự xuất hiện như vậy.

Nếu indexOf() trả về -1 và bạn gọi a.substring(len-pos), thông số sẽ là len - (-1) = len + 1. Đó là nguyên nhân của out of range.

trường hợp này luôn luôn xảy ra trong mã của bạn, vì hai dòng gương:

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

Nếu bạn kiểm tra bằng trước khi gọi phương thức, một trong những pos sẽ luôn luôn trở thành -1. Rõ ràng: nếu một chuỗi chứa một chuỗi khác và chúng không bằng nhau, thì chuỗi thứ hai không chứa chuỗi đầu tiên.

1

Một sự kết hợp của length()regionMatches(int toffset, String other, int ooffset, int len) nên được khá hiệu quả:

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)); 
}