Implement strStr(), string matching-Java

Implement the strStr() function.

Given a haystack string and a needle string, find the first position of the needle string in the haystack string (starting from 0). If it does not exist, it returns -1.

Example 1:
Input: haystack = "hello", needle = "ll"
Output: 2

Example 2:
Input: haystack = "aaaaa", needle = "bba"
Output: -1

Explanation:
When needle is an empty string, what value should we return? This is a good question in an interview.
For this question, we should return 0 when needle is an empty string. This is consistent with the definition of strstr() in C language and indexOf() in Java.

Source: LeetCode Link: https://leetcode-cn.com/problems/implement-strstr

Method 1: Compare the substrings one by one

The most straightforward method-move the sliding window step by step along the character change, and compare the substring in the window with the needle string.
Insert picture description here

public static int strStr(String haystack, String needle) {
    
    
    int L = needle.length(), n = haystack.length();

    for (int start = 0; start < n - L + 1; ++start) {
    
    
        if (haystack.substring(start, start + L).equals(needle)) {
    
    
            return start;
        }
    }
    return -1;
}

Method two: double pointer

The flaw of the previous method is that all substrings of length L of haystack are compared with the needle string, which is actually unnecessary.
First of all, the comparison is only required when the first character of the substring is the same as the first character of the needle string .
Insert picture description here
Secondly, it can be compared character by character, and it terminates immediately if it does not match.
Insert picture description here
As shown in the figure below, a mismatch is found when the last bit is compared, and the backtracking starts at this time. It should be noted that the pn pointer is moved to the position of pn = pn-curr_len + 1, not the position of pn = pn-curr_len.
Insert picture description here
At this time, we compare again and find a complete matching substring, and return the starting position pn-L of the substring directly.
Insert picture description here

algorithm

  • Move the pn pointer until the character at the position pointed to by pn is equal to the first character of the needle string.
  • Calculate the matching length through pn, pL, and curr_len.
  • If it matches exactly (ie curr_len == L), return the starting coordinates of the matched substring (ie pn-L).
  • If it doesn't match exactly, backtrack. Let pn = pn-curr_len + 1, pL = 0, and curr_len = 0.
public static int strStr2(String haystack, String needle) {
    
    
    //needle和haystack的长度
    int L = needle.length(), n = haystack.length();
    if (L == 0) return 0;

    //haystack当前的指针索引
    int pn = 0;
    while (pn < n - L + 1) {
    
    
        //在haystack字符串中找到与needle字符串第一个字符相等的字符的位置
        while (pn < n - L + 1 && haystack.charAt(pn) != needle.charAt(0)) pn++;

        //计算最大匹配字符串
        int currLen = 0;//匹配的长度
        int pL = 0;//needle当前的指针索引
        //通过 pn,pL,curr_len 计算匹配长度
        while (pL < L && pn < n && haystack.charAt(pn) == needle.charAt(pL)) {
    
    
            pn++;
            pL++;
            currLen++;
        }

        //如果needle字符串被找到,返回needle字符串出现的第一个位置
        if (currLen == L) return pn - L;

        //否则,回滚pn
        pn = pn - currLen + 1;
    }
    return -1;
}

Guess you like

Origin blog.csdn.net/m0_46390568/article/details/107525656