Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing substrings in Java

Tags:

java

string

I am writing a method which will return true if either of the Strings appear at the very end of the other String, and the Strings are different. We cannot use endsWith()

For example:

  • if a = "all" and b = "ball", the method would return true.

  • if a = "yes" and b = "yes", the method would return false.

Here's what I have so far but it keeps saying string index out of range= -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;
}
like image 856
Maria Avatar asked Sep 26 '15 19:09

Maria


People also ask

Can you compare substrings in Java?

Using String. equals() :In Java, string equals() method compares the two given strings based on the data/content of the string. If all the contents of both the strings are same then it returns true. If any character does not match, then it returns false.

Can we compare two strings using == in Java?

You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.

How do you know if two substrings are equal?

The equals() method compares two strings, and returns true if the strings are equal, and false if not. Tip: Use the compareTo() method to compare two strings lexicographically.

How do I compare two numeric strings in Java?

You can convert a numeric string into integer using Integer. parseInt(String) method, which returns an int type. And then comparison is same as 4 == 4 .


4 Answers

A combination of length() and regionMatches(int toffset, String other, int ooffset, int len) should be quite efficient:

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));
}
like image 103
xehpuk Avatar answered Sep 28 '22 20:09

xehpuk


It's a bit of "look before you leap", but what you want to do is:

  • Check the index location of each string within another.
  • If (and only if) the index location exists, check to see if the substring from that index spot all the way to the end matches.
  • Otherwise, return false.

If you do any sort of subtraction, you're not going to get the correct size of substring; that is, if you subtract the length of the string you're checking against, you're only going to get one character.

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

Here's a more optimized form of the same code, as pointed out in the comments. Fundamentally it's the same, but you don't need to perform another equals check on the substring, since lastIndexOf would only ever give you the last index of the whole substring.

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;
    }
}
like image 25
Makoto Avatar answered Sep 28 '22 21:09

Makoto


Since you can't use endsWith, first test for null. Then get the lengths. Test that they aren't the same. Check the indexOf + length is equal for true. Something like

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

which I tested like

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

and got the (requested) output

true
false
like image 32
Elliott Frisch Avatar answered Sep 28 '22 22:09

Elliott Frisch


indexOf(String s)

Returns: the index of the first occurrence of the specified substring, or -1 if there is no such occurrence.

If indexOf() returned -1 and you call a.substring(len-pos), the parameter will be len - (-1) = len + 1. That's the cause of out of range.

This case happens always in your code, because of two mirror lines:

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

If you checked equals before method call, one of pos always will became -1. It is obvious: if one string contains another, and they are not equal, then the second string doesn't contain first.

like image 24
serhii Avatar answered Sep 28 '22 22:09

serhii