Find index of next word after the given word

94 Views Asked by At

I am trying to write a Java function with the following parameters:

  • String str: the sample text
  • String word: a word
  • String nextWord: another word

If I pass a given str, a word, and nextWord parameters, it should return me the index of first occurrence of nextWord calculated from the word word, if there are any, otherwise it should return -1.

Suppose I have the following String for the 1st parameter:

String s = "Hatred was spreading everywhere, blood was being spilled everywhere, wars were breaking out everywhere      and dinosaurs are everywhere, but please note I want the first and index.";

In the function I will pass String s as the value of str parameter, "everywhere" literal for word, and "and" liter for nextWord, respectively.

If "and" is just after "everyWhere" as in the above String, it returns me the index of "and", otherwise it returns -1.

I would like to avoid using Regex.

I tried with the following sample code:

public static int indexOfPreceded(String str, String word, String nextWord) {
    int i = StringUtils.indexOfIgnoreCase(str, nextWord);
    if (i < 0) {
        return -1;
    }
    
    return StringUtils.indexOfIgnoreCase(str, word, i + nextWord.length());
}

Executing the code above, with the following str parameter (where the word "and" is not after "everywhere"), "and" for word, and "everywhere" for nextWord:

String s =  "Hatred was spreading everywhere, blood was being spilled everywhere, wars were breaking out everywhere dinosaurs are everywhere, but please note I want the first and index.";

Since in the String s, there is no "and" before "everywhere", I expect -1 as result, but my function returns 158 as the index.

3

There are 3 best solutions below

1
John On

You need to modify your function to properly check if the nextWord appears just after the word. The approach should be to find the index of the word first, and then check if the nextWord immediately follows it.

public static int indexOfPreceded(String str, String word, String nextWord) {
    int currentIndex = 0;
    int wordIndex = -1;
    
    while ((wordIndex = str.indexOf(word, currentIndex)) != -1) {
        int nextWordIndex = wordIndex + word.length();
        int endIndex = nextWordIndex + nextWord.length();

        if (endIndex <= str.length() && str.substring(nextWordIndex, endIndex).equals(nextWord)) {
            return nextWordIndex;
        }

        currentIndex = nextWordIndex;
    }

    return -1;
}
0
Mushroomator On

Assuming you want to return the first occurrence of the described scenario a simple while loop like the following will to the trick.

public class Main {
    public static void main(String[] args) {
        var sentence = "Hatred was spreading everywhere, blood was being spilled everywhere, wars were breaking out everywhere      and dinosaurs are everywhere, but please note I want the first and index.";

        // your sample
        var word = "and";
        var nextWord = "everywhere";
        System.out.println(indexOfFirstWordPrecededBy(sentence, word, nextWord));

        // other tests
        var words = sentence.split(" ");
        var i = 4;
        System.out.println(indexOfFirstWordPrecededBy(sentence, words[i], words[i+1]) == i + 1);
        System.out.println(indexOfFirstWordPrecededBy(sentence, words[i-1], words[i]) == i);
        System.out.println(indexOfFirstWordPrecededBy(sentence, words[i], words[i]) == -1);
        System.out.println(indexOfFirstWordPrecededBy(sentence, words[i+1], words[i]) == -1);
        System.out.println(indexOfFirstWordPrecededBy(sentence, words[i], words[i+2]) == -1);
        System.out.println(indexOfFirstWordPrecededBy(sentence, words[i], "somearbitrarywordthatdoesnotexistinthesentence") == -1);
        System.out.println(indexOfFirstWordPrecededBy(sentence, "somearbitrarywordthatdoesnotexistinthesentence", words[i]) == -1);
    }

    // Assumption: you want to return the first occurrence
    public static int indexOfFirstWordPrecededBy(String sentence, String word, String nextWord){
        var words = sentence.split(" ");
        for (int i = 0; i < words.length - 1; i++) {
            if(words[i].compareToIgnoreCase(word) == 0 && words[i+1].compareToIgnoreCase(nextWord) == 0){
                return i + 1;
            }
        }
        return -1;
    }
}

Expected output:

-1
true
true
true
true
true
true
true

Please note: This implementation doesn't handle some of the edge cases which you should think of. For example it currently only handles single spaces as word separators, you wanna think about how to handle multiple blanks, ,, - or other punctuation marks typically found in sentences. As an example consider word = "spreading" and nextWord = "everywhere": This should probably return 3 but doesn't since the program currently does consider , to be part of the word therefore word = "spreading" and nextWord = "everywhere," will return 3.

In terms of performance this is O(n) but it creates a lot of strings on the heap which have to be garbage collected so there are more efficient implementations possible, but for most purposes this should be just fine.

0
sharma.mahesh369 On
public class Main {
public static void main(String[] args) {
    String inputString = "Hatred was spreading everywhere and, blood was being spilled everywhere, wars were breaking out everywhere and dinosaurs are everywhere, but please note I want the first and index.";
    String wordToFind = "everywhere";
    String nextWord = " and";

    List<Integer> occurrences = findOccurrences(inputString, wordToFind);
    System.out.println("Occurrences of '" + wordToFind + "': " + occurrences);

    if(occurrences.isEmpty())
    {
        System.out.println("Word 'and' not found after 'everywhere' in the string or return -1");
        return;
    }

    for (int index : occurrences) {
        int startPoint = index + wordToFind.length();
        String wordAfterEverywhere = inputString.substring(startPoint, startPoint + nextWord.length());

        if (wordAfterEverywhere.equalsIgnoreCase(nextWord)) {
            System.out.println("Word 'and' found after 'everywhere' at index: " + startPoint);
        } else {
            System.out.println("Word 'and' not found after 'everywhere' in the string or return -1");
        }
    }
}

private static List<Integer> findOccurrences(String inputString, String wordToFind) {
    int index = inputString.indexOf(wordToFind);
    int count = 0;
    ArrayList<Integer> indexList = new ArrayList<>();

    while (index != -1) {
        count++;
        System.out.println("Occurrence " + count + " found at index: " + index);
        indexList.add(index);
        index = inputString.indexOf(wordToFind, index + 1);
    }

    if (count == 0) {
        System.out.println("No occurrences of the word \"" + wordToFind + "\" found.");
    } else {
        System.out.println("Total occurrences of the word \"" + wordToFind + "\": " + count);
    }

    return indexList;
}

}