Home > Back-end >  Why does my Java code output 10 instead of -1 in this situation, and how do I fix it?
Why does my Java code output 10 instead of -1 in this situation, and how do I fix it?

Time:12-12

I'm making a static method, "indexOfKeyword", and it is meant to return an indexOf a string when the string isn't embedded into another word—it's meant to return -1 when that does not occur.

Given

String s = "She sells seashells by the seashore.";
String keyword = "sea";

the output is meant to be -1 because the keyword "sea" is embedded into each word; however, my code outputs 10 instead, the first occurrence where it finds "sea" in "seashells".

If a string has an occurrence where it stands alone in the beginning, like

String s = "Carolyn has a car that is scary fast.";
String keyword = "car";

I made it where startIdx has to be greater than 0 so that the "Car" in "Carolyn" does not get picked up. When the above is inputted into the code below, it works as intended, outputting correctly 14.

Here is the code in its entirety, verbatim, that should be outputting -1:

public class Chatter {
    public static int indexOfKeyword(String s, String keyword) {
        s = s.toLowerCase();
        keyword = keyword.toLowerCase();
        int startIdx = s.indexOf(keyword);
        while (startIdx >= 0) {
            String before = " ", after = " ";
            if (startIdx > 0) {
                before = s.substring(startIdx - 1, startIdx);
            }
            int endIdx = startIdx;
            if (endIdx < s.length()) {
                after = s.substring((startIdx   keyword.length()), (startIdx   keyword.length()   1));
            }
            if (!(before.compareTo("a") >= 0 && before.compareTo("z") <= 0 && after.compareTo("a") >= 0
                    && after.compareTo("z") <= 0)) {
                if (startIdx > 0) {
                    return startIdx;
                }
            }
            startIdx = s.indexOf(keyword, s.indexOf(keyword)   1);
        }
        return -1;
    }

    public static void main(String[] args) {
        // ... and test it here
        String s = "She sells seashells by the seashore.";
        String keyword = "sea";
        System.out.println(indexOfKeyword(s, keyword));
    }
}

CodePudding user response:

I understand that you want to find a particular word and not a particular substring.

There are two errors in your method indexOfKeyword.

  1. The condition in the while loop is wrong. You need to split it into two, separate conditions.
  2. Setting startIdx, in order to search for the next occurrence of keyword is also wrong.

Compare your code with the code below.

public static int indexOfKeyword(String s, String keyword) {
    int startIdx = s.indexOf(keyword);
    while (startIdx >= 0) {
        String before = " ", after = " ";
        if (startIdx > 0) {
            before = s.substring(startIdx - 1, startIdx);
        }
        int endIdx = startIdx;
        if (endIdx < s.length()) {
            after = s.substring((startIdx   keyword.length()), (startIdx   keyword.length()   1));
        }
        if (!(before.compareTo("a") >= 0 && before.compareTo("z") <= 0)) {
            if (!(after.compareTo("a") >= 0 && after.compareTo("z") <= 0)) {
                if (startIdx > 0) {
                    return startIdx;
                }
            }
        }
        startIdx = s.indexOf(keyword, startIdx   1);
    }
    return -1;
}

As @Tom mentioned, in his comment, there are other ways to solve the problem. I assume that your purpose is to come up with and implement your own algorithm, hence I have shown you were you have gone wrong in your implementation.

Note that a single space is not the only way to delimit words in a sentence, for example two words, in a sentence, may be separated by a comma.

CodePudding user response:

I'm sorry, mayby I've got your intentions incorrectly, but have you considered wrapping your keyward with spaces before searching?

Something like this should (theoretically) work:

public static int indexOfKeyword(String s, String keyword) {
    String source = s.toLowerCase();
    String key = " "   keyword.toLowerCase()   " ";
    return source.indexOf(key);
}

Or (as @Tom has noted) RegEx might be used, however this solution is more complicated and might be not as obvious as you wanted it to be.

In your case it might look like this:

public static int indexOfKeyword(String s, String keyword) {
    Matcher m = Pattern.compile("\\s"   keyword   "\\s", Pattern.CASE_INSENSITIVE).matcher(s);
    return m.find() ? m.start() : -1;
}
  •  Tags:  
  • java
  • Related