Naive String Search

The simplest string search: place the pattern at every position of the text and compare letter by letter.

Worth knowing first

#How does it work?

String matching means finding every position where a pattern occurs in a text. The simplest method places the pattern at every possible starting position of the text and compares letter by letter.

At each shift the comparison starts at the beginning of the pattern and stops at the first mismatch; the pattern moves one step right and everything starts over. If every letter matches, a match is found.

It is fast on most real text, because mismatches usually show up within the first few letters. But on repetitive text such as AAAA…AB the same letters are compared again and again and the cost rises to O(n · m).

#Try it yourself

$ naive_string-search --interactive

The pattern slides under the text from left to right. At every shift the letters are compared one by one from the start.

VisitingNewRemovingFound / read

#Step by step

  1. 01Align the pattern with the first position of the text.
  2. 02Compare letters from the start; stop at the first mismatch.
  3. 03If every letter matched, record the match.
  4. 04Move the pattern one step right and repeat up to the last position.

#Example code

The same algorithm in 8 languages. Every program is compiled, run and checked to print the same output.

def search(text: str, pattern: str) -> list:
    """Every 0-based position where pattern starts in text."""
    n, m = len(text), len(pattern)
    found = []
    for s in range(n - m + 1):  # every shift of the pattern
        j = 0
        while j < m and text[s + j] == pattern[j]:
            j += 1
        if j == m:
            found.append(s)
    return found


print(" ".join(map(str, search("AABAACAADAABAABA", "AABA"))))

#Complexity

OperationTime
Worst caseO(n · m)
Average (random text)O(n)
PreprocessingNone
MemoryO(1)

n is the text length and m the pattern length. The pattern is tried at n − m + 1 shifts with at most m comparisons each. Since it needs no preprocessing, it remains a good choice for short patterns and one-off searches.

#When to use it?

Short patterns and short texts, one-off searches and places where simplicity matters. Many standard libraries' indexOf / find use an optimised form of this method for short inputs.

#Practice

Log in to answer questions and save your progress.

Easy

1/3

What does naive search do after a mismatch?

  • 1Moves the pattern one step right and starts comparing from its first letter
  • 2Jumps to the end of the text
  • 3Moves the pattern two steps
  • 4Stops searching

Medium

1/1

Which text and pattern give naive search its worst case?

  • 1Text AAAA…A, pattern AAA…AB
  • 2Text and pattern share no letters
  • 3The pattern is at the start of the text
  • 4The pattern is one letter

Hard

1/1

Why do many libraries still use naive search?

  • 1It needs no preprocessing and is very fast for short patterns in practice
  • 2It is the fastest in the worst case
  • 3It uses O(n · m) memory
  • 4It only works on sorted text

#Up next

Lessons that build on this one: