artifc3
artifc3

Reputation: 77

Leetcode 28 - Implement strStr(): question

I am experiencing a bug in my submissions for Leetcode 28 that has thus far eluded me. My code works for most test cases but I am getting hung up on scenarios such as haystack = "mississippi", needle = "issip".

I have tried debugging and found that the entire haystack string is iterated through and it is returning -1 or not found. The substring length it is finding at each occurrence of 'i' is 4, 1, 1.

int strStr(string haystack, string needle) {
        if (needle.empty()) {
            return 0;
        }
        if (haystack.empty() && !needle.empty()) {
            return -1;
        }
        int i = 0, j = 0, ans = 0;
        for (i; i < haystack.length(); i++) {
            if (haystack[i] == needle[0]) {
                j = 0;
                ans = i;
                for (j; j < needle.length(); j++) {
                    /*
                    if (haystack[i++] == needle[j]) {
                        continue;
                    }
                    else {
                        break;
                    }
                    */
                    if (haystack[i++] != needle[j]) {
                        break;
                    }
                }
                if (j == needle.length()) {
                    return ans;
                }
            }
            if (j == needle.length()) {
            return ans;
            }
        }
        return -1;
    }

Input: "mississippi", "issip" Output: -1 (ans = 10, j = 1)

Upvotes: 2

Views: 1007

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 311048

The function has several drawbacks.

For starters it should be declared like

std::string::size_type strStr( const std::string &haystack, const std::string &needle );

and if the second string is not found in the first string the function should return std::string::npos as all similar member functions of the class std::string do.

The function parameters shell be of constant referenced types.

The condition in this if-statement

if (haystack.empty() && !needle.empty())

has a redundant operand. It could be rewritten like

if (haystack.empty())

This loop

for (i; i < haystack.length(); i++) 

should stop its iterations when the size of the tail of the first string is less than the size of the second string.

in this if-statement

if (haystack[i++] != needle[j]) {

the variable i is incremented that results in incrementing the variable two times: one in this statement and the second time in the loop.

The second pair of these statements

        if (j == needle.length()) {
        return ans;

is redundant.

The function can be written the following way as it is shown in the demonstrative program.

#include <iostream>
#include <string>

std::string::size_type strStr( const std::string &haystack, const std::string &needle )
{
    if ( needle.empty() )
    {
        return 0;
    }
    else if ( haystack.empty() )
    {
        return -std::string::npos;
    }
    else
    {
        std::string::size_type ans = std::string::npos;

        auto n1 = haystack.length();
        auto n2 = needle.length();

        for ( std::string::size_type i = 0; ans == std::string::npos && i + n2 <= n1; i++ )
        {
            std::string::size_type j = 0;
            while ( j < n2 && haystack[i+j] == needle[j] ) j++;

            if ( j == n2 ) ans = i;
        }

        return ans;
    }
}

int main() 
{
    std::string haystack( "mississippi" );
    std::string needle( "issip" );

    std::cout << strStr( haystack, needle ) << '\n';

    return 0;
}

Its output is

4

Upvotes: 3

Jeffrey
Jeffrey

Reputation: 11430

The problem is that you modify i in

if (haystack[i++] != needle[j]) {

Thus preventing a second potential match from being explored. Try

if (haystack[i + j] != needle[j]) {

and fix any knock-on issues. I expect it to work as-is, though.

Upvotes: 2

Related Questions