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

Answer from Vlad from Moscow on Stack Overflow
🌐
Red Quark
redquark.org › leetcode › 0028-implement-strstr
LeetCode #28 - Implement StrStr | Red Quark
Hello fellow devs 👋! We have a new LeetCode problem today involving string. ... Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. What should we return when needle is an empty string? This is a great question to ask during an interview. For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C’s strstr() and Java’s indexOf().
🌐
GitHub
github.com › vli02 › leetcode › blob › master › 28. Implement strStr().c
leetcode/28. Implement strStr().c at master · vli02/leetcode
Implement strStr(). ... Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Author   vli02
🌐
Codeewander
codeewander.github.io › leetcode 28 - implement strstr()
LeetCode 28 - Implement strStr() | Kira Yang
Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. ... What should we return when needle is an empty string? This is a great question to ask during an interview. For the purpose of this problem, we will return 0 when ...
🌐
Leetcode
articles.leetcode.com › implement-strstr-to-find-substring-in
Implement strstr() to Find a Substring in a String – LeetCode
When you are comparing each character of the two strings via: while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; } you can record the next character that equals *target. Then if this comparison doesn’t give a match, you can start directly from the next location instead of doing p1 = p1Begin + ...
🌐
Gitbook
aaronice.gitbook.io › lintcode › string › implement-strstr
Implement strStr() | LintCode & LeetCode
public class Solution { /** * @param source: * @param target: * @return: return the index */ public int strStr(String source, String target) { // Write your code here if (target.equals("")){ return 0; } for (int i = 0; i < source.length() - target.length() + 1; i++){ int j = 0; int k = i; while (j < target.length() && k < source.length()){ if (source.charAt(k) == target.charAt(j)){ k++; j++; } else { break; } } if(j == target.length()){ return k - target.length(); } } return -1; } }
Top answer
1 of 2
3

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

2 of 2
2

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.

🌐
Medium
lenchen.medium.com › leetcode-28-implement-strstr-64de75d9ffb1
LeetCode #28 Implement strStr(). Easy (not that easy actually) | by Len Chen | Medium
September 17, 2018 - LeetCode #28 Implement strStr() Easy (not that easy actually) Problem Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of …
🌐
Medium
medium.com › @edwardllookk › day-9-implement-strstr-c-solution-41a255b1b05d
Day 9: Implement strStr() — C++ solution | by Ed | Medium
January 15, 2019 - class Solution { public: int strStr(string haystack, string needle) {int h_sz = haystack.size(); int n_sz = needle.size(); if (!n_sz) { return 0; } for (int i = 0; i < h_sz; i ++) { if (haystack[i] == needle[0]) { int j = 0; for (; j < n_sz; j++) { if (haystack[i+j] != needle[j]) break; } if (j == n_sz) return i; } } return -1; } }; With the idea of using brute-force, this question can be broke down into two stages: first character matching and complete strings matching.
Find elsewhere
🌐
GitBooks
cheonhyangzhang.gitbooks.io › leetcode-solutions › content › 28_implement_strstr__easy.html
28 Implement strStr() – Easy · LeetCode solutions
Implement strStr(). Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. Very straightforward. String manipulation. public class Solution { public int strStr(String haystack, String needle) { if (needle.equals("")) { return 0; } for (int ...
🌐
LeetCode
leetcode.com › problems › find-the-index-of-the-first-occurrence-in-a-string › solutions › 1326344 › c-implement-strstr-solution
Find the Index of the First Occurrence in a String - LeetCode
Find the Index of the First Occurrence in a String - Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
🌐
Beizhedenglong
beizhedenglong.github.io › leetcode-solutions › docs › implement-strstr
Implement strStr() · LeetCode Site Generator
/** Rabin-Karp * @param {string} haystack * @param {string} needle * @return {number} */ const strStr = function (haystack, needle) { const base = 256 const prime = 1439173969 if (needle === '') { return 0 } let hashNeedle = 0 const magic = (base ** (needle.length - 1)) % prime const product = prime * base for (const c of needle) { hashNeedle = (hashNeedle * base + c.charCodeAt(0)) % prime } const isEqual = i => needle === haystack.slice(i, i + needle.length) let hash = 0 for (let i = 0; i <= haystack.length - needle.length; i++) { if (i === 0) { for (let j = 0; j < needle.length; j++) { hash = (hash * base + haystack[j].charCodeAt(0)) % prime } } else { hash = (hash - haystack[i - 1].charCodeAt(0) * magic + product) % prime hash = (hash * base + haystack[i + needle.length - 1].charCodeAt(0)) % prime } if (hash === hashNeedle && isEqual(i)) { return i } } return -1 }
🌐
Codesays
codesays.com › 2014 › solution-to-implement-strstr-by-leetcode
Solution to Implement strStr() by LeetCode – Code Says
Fabien November 7, 2024 at 4:42 am on Unofficial Solutions to the Training by CodilitySimilar but more compact solution using C++17 or later: #include <stack> #include <vector> using namespace std; using point = pair<int, int>; stack<point> pending; void explore(const...
🌐
LeetCode
leetcode.ca › all › 28.html
Leetcode 28. Implement strStr()
What should we return when needle is an empty string? This is a great question to ask during an interview. For the purpose of this problem, we will return 0 when needle is an empty string. This is consistent to C's strstr() and Java's indexOf().
🌐
Eugenejw
eugenejw.github.io › 2017 › 07 › leetcode-28
Weihan's Coding Blog | Implement strStr method (leetcode 28)
public class Solution { /** * Return the starting index of the first needle found in haystack * @param String haystack of type String * @param String needle of type String * @return int the starting index */ public int strStr(String haystack, String needle) { int[] kmpTable= new int[needle.length()]; buildKMPTable(needle, kmpTable); int i = 0; int j = 0; int N = haystack.length(); int M = needle.length(); while (i < N && j < M) { if (haystack.charAt(i) == needle.charAt(j)) { i++; if (++j == M) { return i - j; } } else { if (j == 0) { i++; } else{ j = kmpTable[j-1]; } } } if (M == 0) return 0;
🌐
Airtribe
airtribe.live › dsa-sheet › resource › implement-strstr
Mastering KMP Algorithm: Efficiently Finding the First Occurrence of a Substring
The challenge is to implement a function that finds the needle (substring) in the haystack (string) and returns the index of its first occurrence. It’s essentially the same as using the indexOf method provided in most programming languages.
🌐
Stack Overflow
stackoverflow.com › questions › 72795129 › leetcode-28-implement-strstr-why-my-code-failed
debugging - Leetcode 28. Implement strStr() -- Why my code failed? - Stack Overflow
My code failed on haystack = "hello", needle = "ll". Expected: 2, my output: -1. Here's my code: class Solution { public int strStr(String haystack, String needle) { if (nee...
🌐
Gitbook
hannahpun.gitbook.io › leetcode-note › string › 28-implement-strstr
# 28 Implement strStr() | LeetCode Note
BF 165. remove characters ... Implement strStr(). Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. Example 1: Input: haystack = "hello", needle = "ll" Output: 2 Example 2: Input: haystack ...
🌐
DEV Community
dev.to › rohan2596 › leetcode-implement-strstr-with-solution-474a
LeetCode :-Implement strStr() with Solution - DEV Community
June 2, 2022 - Implement strStr(). Given two strings needle and haystack, return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack. ... What should we return when needle is an empty string?
Top answer
1 of 2
1

The problem is you increment i inside the inner loop and again in the outer loop, potentially skipping the null terminator, hence accessing bytes in haystack beyond the end, which has undefined behavior.

You should only increment j in the inner loop and compare haystack[i + j] == needle[j].

Here is a modified version:

#include <stdio.h>

int strStr(const char *haystack, const char *needle) {
    if (needle[0] == '\0')
        return 0;

    int i = 0;

    while (haystack[i] != '\0') {
        int j = 0;
        while (needle[j] != '\0' && haystack[i + j] == needle[j]) {
            j++;
        }
        if (needle[j] == '\0') {
            return i;
        }
        i++;
    }
    return -1;
}

int main() {
    printf("%d\n", strStr("aaaaaaaaab", "aaaab"));
    printf("%d\n", strStr("aaaaaaaa", "aaaaaaaaa"));
    printf("%d\n", strStr("Hello world\n", "or"));
    return 0;
}

Note that you can remove some redundant comparisons by reorganising the code:

int strStr(const char *haystack, const char *needle) {
    for (int i = 0;; i++) {
        for (int j = 0;; j++) {
            if (needle[j] == '\0')
                return i;
            if (haystack[i + j] != needle[j])
                break;
        }
        if (haystack[i] == '\0')
            return -1;
    }
}

Note however that this method has a worst case time complexity of O(len(haystack)*len(needle)), with a pathological example of:

strStr("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaaaaaaaaab")
2 of 2
1

In the function strStr(), when i and j both equal to 3, the nested while loop exits because the condition haystack[i] != '\0' becomes false. Below in the code, it check for needle[j] == '\0' which is false as for j = 3, needle[j] is not equal to \0. Then it increments i which makes value of i equal to 4 and the outer while loop iterates and check the condition haystack[i] != '\0' which results in accessing haystack beyond the size of buffer it is pointing to because the valid index for the buffer that haystack is pointing to is range from 0 - 3 (string - "aaa").

Since, you have posted AddressSanitizer output, below is the explanation of how to interpret ASan output and identify the problem:

The error reported by ASan is:

ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000014

buffer-overflow means your program is trying to access memory beyond the size of array, precisely trying to access the string literal beyond its size1).

Check this statement in the ASan output:

0x602000000014 is located 0 bytes to the right of 4-byte region [0x602000000010,0x602000000014)

This means program attempting to access address 0x602000000014 which exists 0 bytes right to 4-byte region [0x602000000010,0x602000000014).

A point to note here for region [0x602000000010,0x602000000014) - square brackets [ mean the end point is included, and round parentheses ) mean it's excluded.

The 4-byte region 0x602000000010 - 0x602000000013 contain the string literal "aaa" which is pointed by haystack pointer:

                         0x602000000014
                  0x602000000013      |
            0x602000000012     |      |
      0x602000000011     |     |      |
0x602000000010     |     |     |      |
             |     |     |     |      |
            +-----+-----+-----+------+-----+
            |  a  |  a  |  a  |  \0  |     |
            +-----+-----+-----+------+-----+
             \                      /
              +--------------------+
                        |
             4-byte region pointed 
              by haystack pointer

Note that ASan creates poisoned red zones at the edges of objects to detect overflows or underflows and during compilation ASan instruments the code to verify the shadow memory state at each memory access2). 1 byte of shadow memory keeps the track of 8 bytes of memory used by ASan instrumented program.

Now, check this section of ASan output:

Shadow bytes around the buggy address:

in the output, a memory region is highlighted with => :

=>0x0c047fff8000: fa fa[04]fa fa fa 05 fa fa fa fa fa fa fa fa fa
                       ^^^^

In [04] -

  • 04 indicates that first four bytes of 8 byte region (which are mapped with this byte in shadow memory) are addressable. That means the memory region from 0x602000000010 to 0x602000000013 contain "aaa" (including null terminating character) are addressable.
  • square bracket [] indicates that your program trying to access the redone (basically, the memory which is not allowed to access) which are mapped to this byte in shadow memory.

Your program trying to access the byte just next to terminating null character \0 of string "aaa" and ultimately attempting to access redzone and, hence, the ASan reporting it.

The other post already shown the better implementation of strStr(). I am leaving it up to you to fix the problem in your code and optimise the implementation of strStr() function.

A suggestion:

When compiling program with -fsanitize=address, enable the debugging information as well (e.g. -g option of gcc compiler) and you will get line number and proper stack in the ASan output.


1). Not sure why it's reporting heap-buffer-overflow for accessing string literal beyond its size. On my system ASan output for same program giving error - global-buffer-overflow, which seems more appropriate as the string literals usually allocated in data segment but where they will be placed can vary based on underlying platform/architecture.

2). AddressSanitizer - How it works?

🌐
GeeksforGeeks
geeksforgeeks.org › problems › implement-strstr › 1
Implement strstr | Practice | GeeksforGeeks
Given two strings txt and pat, return the 0-based index of the first occurrence of the substring pat in txt. If pat is not found, return -1.Note: You are not allowed to use the inbuilt function. Examples : Input: txt = "GeeksForGeeks", pat = "Fr