0

I am trying to write a program that takes a string and removes all instances of another string from it. For example: ("Remove them all!", "em") would print "Rove th all!". However, when I do run this, it give me java.lang.StringIndexOutOfBoundsException.

public class LabFive {

    public static String removeAll(String oldPhrase, String removal){
        String newPhrase = "";
        for(int i = 0; i <= oldPhrase.length(); i++){
            if(oldPhrase.substring(i, (removal.length() + i)) == removal)
                newPhrase = newPhrase + oldPhrase.substring((removal.length() + 2 + i), oldPhrase.length());        
        }
        return(newPhrase);
    }

    public static void main(String[] args) {
        System.out.println(removeAll("AaAaAa", "a"));
    }
}
jrbedard
  • 3,662
  • 5
  • 30
  • 34

2 Answers2

0

Your code seems to have several issues. Firstly, you can't use == to check for string equality, you have to use String.equals() method. Read here.

Secondly, your for loop iterates from 0 to oldPhrase.length() inclusive, but trying to use this length value for index will cause the exception to occur. In java, strings have zero-based index, so index starts from 0 and ends at oldPhrase.length()-1.

Third, your logic seems broken. The substring(int, int) method's parameters are beginIndex and endIndex. So:

newPhrase = newPhrase + oldPhrase.substring((removal.length() + 2 + i), oldPhrase.length());

concatenating part of the oldPhrase till the end to the newPhrase is not going to do what you want.


Here is the way I did it. The idea is simpler, and also clearer. I have added comment to make it clear.

Test the code live on Repl.it

public static String removeAll(String oldPhrase, String removal) {

    // if removal is not found return the original string
    if(oldPhrase.indexOf(removal) == -1) {
        return oldPhrase;
    }

    int removalLength = removal.length(); // storing the length so as not to call .length() again and again

    for(int i = 0; i < oldPhrase.length(); i++) { // note that <= will cause the exception too
        int idxOfRemoval = oldPhrase.indexOf(removal);

        if(idxOfRemoval == i) { // removal is found at the current index, i.e. at index i
            // take substring from beginning to index of removal +
            // substring from the end of removal to end of original string
            oldPhrase = oldPhrase.substring(0, idxOfRemoval) + oldPhrase.substring(idxOfRemoval+removalLength);
        }
    }
    return(oldPhrase);
}

public static void main(String[] args) {
    System.out.println(removeAll("AaAaAa", "a"));
}

Output:

AAA
Community
  • 1
  • 1
Sнаđошƒаӽ
  • 16,753
  • 12
  • 73
  • 90
0

The easiest way to explain the java.lang.StringIndexOutOfBoundsException is in your loop:

for(int i = 0; i <= oldPhrase.length(); i++){...}

since i is going to be equal to oldPhrase.length() you have a problem with getting the substring:

oldPhrase.substring(i, (removal.length() + i))

so you end up with eventually

oldPhrase.substring(oldPhrase.length(), (removal.length() + oldPhrase.length()))

This is a problem because the highest index in a string is length - 1 and you're trying to access the index at length.

A brute force way of doing removeAll would be to iterate over your string (as you did) and just check, for each character at i, if removal starts there and then the string you want to return would be

sub(0,i) + removeAll(the rest off your string starting at i+removal.length)

public static String removeAll(String oldPhrase,String removal) {
    int rem = removal.length();
    int n = oldPhrase.length();
    // if length of oldPhrase is shorter than removal
    // then there nothing you need to remove
    if (n < rem) return oldPhrase;

    // iterate over your string
    for (int i = 0; i <= n - rem; i++) {
        int j;
        // check if there is a substring, removal, starting at i
        for (j = 0; j < rem; j++) {
            if (oldPhrase.charAt(i+j) != removal.charAt(j))
                break;
        }
        // if there is...
        if (j == rem) {
            // return stuff before substring you want to remove +
            //        removeAll(the stuff after substring you want to remove)
            return  oldPhrase.substring(0,i) + removeAll(oldPhrase.substring(i+rem,n),removal);
        }
    }
    return oldPhrase;
}

public static void main(String[] args) {
    System.out.println(removeAll("AaAaAa", "a"));
}

output:

AAA

Bobas_Pett
  • 591
  • 5
  • 10