简体   繁体   中英

Return the number of times query occurs as a substring of src

/** Return the number of times query occurs as a substring of src
 * (different occurrences may overlap).
 * Precondition: query is not the empty string "".
 * Examples: For src = "ab", query = "b", return 1.
 *           For src = "Luke Skywalker", query = "ke", return 2.
 *           For src = "abababab", query = "aba", return 3.
 *           For src = "aaaa", query = "aa", return 3.*/
public static int numOccurrences(String src, String query) {
    /* This should be done with one loop. If at all possible, don't have
     * each iteration of the loop process one character of src. Instead,
     * see whether some method of class String can be used to jump from one
     * occurrence of query to the next. */
    int count = 0;
    for (int i = 0; i < src.length(); i++) {
        int end = i + query.length() - 1;
        if (end < src.length()) {
            String sub = src.substring(i, end);
            if (query.contentEquals(sub)) 
                ++count;
        } 
    }return count;
}

I tested the code. If the src is "cherry" and the query is "err", then the output is expected to be 1 but it turns out to be 0. What's wrong with the code? BTW, I cannot use methods outside the String class.

What's wrong is that you're comparing err to:

i | sub
--|------
0 | ch
1 | he
2 | er
3 | rr

Notice that these strings you're comparing to look short, and you don't even get to the end of "cherry" before you stop checking for a match. So there are two things you need to fix in your code: the way you calculate end and the comparison between end and src.length() .

Hint: the second argument (ending index) to substring is exclusive .

Pseudo code:

init 'count' and 'start' to 0
while true do
  find first occurence of 'query' in 'source', start search at 'start'
  if found
    set 'start' to found position + 1
    set count to count + 1
  else
    break out of while loop
end while
return count

Tip: Use String#indexOf(String str, int fromIndex) when finding occurence of query in source

Check the existence of query in src and loop until it return false. With each occurrence, take the substring , update the count and repeat until query is not found in src.

Pseudo code:

int count = 0;
loop (flag is true) 
  int index = find start index of query in src;
  if (query is found) 
    src = update the src with substring(index + query.length());
    count++;
  else 
    flag = false;      
return count;

This does the job:

public static int numOccurrences(String src, String query) {
    int count = 0;
    for(int i = src.indexOf(query); i > -1;i = src.indexOf(query, i + 1)) 
        count++;
    return count;
}

Here, i is the index of query in src , but the increment term makes use of indexOf(String str, int fromIndex) , which javadoc says:

Returns the index within this string of the first occurrence of the specified substring, starting at the specified index.

which is passed the index i plus 1 to start searching for another occurrence after the previous hit.

This also addresses the NFR hinted at in the comment:

Instead, see whether some method of class String can be used to jump from one occurrence of query to the next.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM