Search the pattern in given String
Last Updated :
15 Mar, 2023
Given two strings, text and pattern, of size N and M (N > M)respectively, the task is to print all occurrences of pattern in text.
Examples:
Input: text = "This is a dummy text", pattern = "This"
Output: Pattern found at indices: 0
Explanation: The pattern "This" starts from index 0 in the given text.
Input: text = "Welcome to Geeks for Geeks", pattern = "Geeks"
Output: Pattern found at indices: 21 11
Explanation: The pattern "Geeks" starts from the 11th and 21st index (considering the white spaces).
Approach: The approach for this problem is based on the following idea:
Find the possible starting indices of all the starting points in the text. Then for all those indices check if their adjacents match with the next elements of the pattern.
The above idea can be implemented using the queue. Follow the steps mentioned below to implement the idea.
- First of all, use a 256 sized array of unordered_set. Traverse through the text and insert every index to the set of the respective character.
C++
for (int i = 0; i < st.length(); i++)
// Insert every index to the hash set using character
// ASCII.
structured_text[st[i]].insert(i);
- Search for the first character of the pattern in the array and push every index contained in the hash set into a queue.
C++
for (int ind : structured_text[pattern[0]])
q_indices.push(ind);
- Then traverse through pattern from i = 1 to M-1:
- If the index in structured_text[pattern[i]] is adjacent to any of the characters present in pat[i-1], push it to the queue for next iteration.
- Otherwise, continue checking for other positions.
C++
for (int i = 1; i < pattern.length(); i++) {
char ch = pattern[i];
int q_size = q_indices.size();
/* the queue contains the number of occurrences of the
previous character. traverse the queue for q_size times
Check the next character of the pattern found or not. */
while (q_size--) {
int ind = q_indices.front();
q_indices.pop();
if (structured_text[ch].find(ind + 1)
!= structured_text[ch].end())
q_indices.push(ind + 1);
}
}
Python3
for i in range(1, pat_len):
ch = pattern[i]
q_size = len(q_indices)
## The queue contains the
## number of occurrences of
## the previous character.
## Traverse the queue for
## q_size times.
## Check the next character of
## the pattern found or not.
while q_size > 0:
q_size -= 1
ind = q_indices[0]
q_indices.pop(0)
if ((ind + 1) in structured_text[ord(ch)]):
q_indices.append(ind + 1)
# This code is contributed by akashish_.
- If the whole pattern is found then return those indices.
Below is the implementation for the above approach:
C++
// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
// Using a 256 sized array of
// hash sets.
unordered_set<int> structured_text[256];
// Function to perform the hashing
void StringSearch(string st)
{
// Structure the text. It will be
// helpful in pattern searching
for (int i = 0; i < st.length(); i++)
// Insert every index to the
// hash set using character ASCII.
structured_text[st[i]].insert(i);
}
// Function to search the pattern
void pattern_search(string st, string pattern)
{
StringSearch(st);
// Queue contain the indices
queue<int> q_indices;
for (int ind : structured_text[pattern[0]])
q_indices.push(ind);
// Pattern length
int pat_len = pattern.length();
for (int i = 1; i < pat_len; i++) {
char ch = pattern[i];
int q_size = q_indices.size();
// The queue contains the
// number of occurrences of
// the previous character.
// Traverse the queue for
// q_size times.
// Check the next character of
// the pattern found or not.
while (q_size--) {
int ind = q_indices.front();
q_indices.pop();
if (structured_text[ch].find(ind + 1)
!= structured_text[ch].end())
q_indices.push(ind + 1);
}
}
cout << "Pattern found at indexes:";
while (!q_indices.empty()) {
// last_ind is the last index
// of the pattern in the text
int last_ind = q_indices.front();
q_indices.pop();
cout << " " << last_ind - (pat_len - 1);
}
cout << endl;
}
// Driver code
int main()
{
// Passing the Text
string text = "Welcome to Geeks for Geeks";
string pattern = "Geeks";
// Function call
pattern_search(text, pattern);
return 0;
}
Python3
# Python program for the above approach:
## Using a 256 sized array of
## hash sets.
structured_text = [set({}) for _ in range(256)]
## Function to perform the hashing
def StringSearch(st):
## Structure the text. It will be
## helpful in pattern searching
global structured_text
for i in range(len(st)):
## Insert every index to the
## hash set using character ASCII.
structured_text[ord(st[i])].add(i)
## Function to search the pattern
def pattern_search(st, pattern):
global structured_text
StringSearch(st)
## Queue contain the indices
q_indices = []
for ind in structured_text[ord(pattern[0])]:
q_indices.append(ind)
## Pattern length
pat_len = len(pattern);
for i in range(1, pat_len):
ch = pattern[i]
q_size = len(q_indices)
## The queue contains the
## number of occurrences of
## the previous character.
## Traverse the queue for
## q_size times.
## Check the next character of
## the pattern found or not.
while q_size > 0:
q_size -= 1
ind = q_indices[0]
q_indices.pop(0)
if ((ind + 1) in structured_text[ord(ch)]):
q_indices.append(ind + 1)
print("Pattern found at indexes:", end="")
while len(q_indices) > 0:
## last_ind is the last index
## of the pattern in the text
last_ind = q_indices[0]
q_indices.pop(0)
print("", last_ind - (pat_len - 1), end="")
print("")
## Driver code
if __name__ == '__main__':
## Passing the Text
text = "Welcome to Geeks for Geeks"
pattern = "Geeks"
## Function call
pattern_search(text, pattern)
# This code is contributed by subhamgoyal2014.
Java
import java.util.HashSet;
import java.util.Queue;
import java.util.LinkedList;
public class PatternSearch {
// Using a 256 sized array of hash sets.
private HashSet<Integer>[] structuredText = new HashSet[256];
// Function to perform the hashing
public void stringSearch(String st) {
// Structure the text. It will be helpful in pattern searching
for (int i = 0; i < 256; i++) {
structuredText[i] = new HashSet<Integer>();
}
// Insert every index to the hash set using character ASCII.
for (int i = 0; i < st.length(); i++) {
structuredText[(int)st.charAt(i)].add(i);
}
}
// Function to search the pattern
public void patternSearch(String st, String pattern) {
stringSearch(st);
// Queue to contain the indices
Queue<Integer> qIndices = new LinkedList<Integer>();
for (int ind : structuredText[(int)pattern.charAt(0)]) {
qIndices.add(ind);
}
// Pattern length
int patLen = pattern.length();
for (int i = 1; i < patLen; i++) {
char ch = pattern.charAt(i);
int qSize = qIndices.size();
// The queue contains the number of occurrences of the previous character.
// Traverse the queue for q_size times.
// Check the next character of the pattern found or not.
while (qSize > 0) {
qSize--;
int ind = qIndices.peek();
qIndices.remove();
if (structuredText[(int)ch].contains(ind + 1)) {
qIndices.add(ind + 1);
}
}
}
System.out.print("Pattern found at indexes: ");
while (!qIndices.isEmpty()) {
// lastInd is the last index of the pattern in the text
int lastInd = qIndices.peek();
qIndices.remove();
System.out.print(lastInd - (patLen - 1) + " ");
}
System.out.println();
}
// Driver code
public static void main(String[] args) {
PatternSearch ps = new PatternSearch();
// Passing the Text
String text = "Welcome to Geeks for Geeks";
String pattern = "Geeks";
// Function call
ps.patternSearch(text, pattern);
}
}
C#
using System;
using System.Collections.Generic;
class GFG {
// Using a Dictionary of lists
// for structuring the text
static Dictionary<char, List<int> > structuredText
= new Dictionary<char, List<int> >();
// Function to perform the hashing
static void StringSearch(string st)
{
for (int i = 0; i < st.Length; i++) {
char ch = st[i];
// Add the index to the list
// of corresponding character
if (structuredText.ContainsKey(ch)) {
structuredText[ch].Add(i);
}
else {
structuredText.Add(ch, new List<int>{ i });
}
}
}
// Function to search the pattern
static void pattern_search(string st, string pattern)
{
StringSearch(st);
// Queue to contain the indices
Queue<int> q_indices = new Queue<int>();
// Add the first index of the
// pattern from the text
if (structuredText.ContainsKey(pattern[0])) {
q_indices = new Queue<int>(
structuredText[pattern[0]]);
}
// Pattern length
int pat_len = pattern.Length;
for (int i = 1; i < pat_len; i++) {
char ch = pattern[i];
int q_size = q_indices.Count;
// Traverse the queue for
// q_size times.
// Check the next character of
// the pattern found or not.
while (q_size-- > 0) {
int ind = q_indices.Dequeue();
if (structuredText.ContainsKey(ch)
&& structuredText[ch].Contains(ind
+ 1)) {
q_indices.Enqueue(ind + 1);
}
}
}
Console.Write("Pattern found at indexes:");
while (q_indices.Count > 0) {
// last_ind is the last index
// of the pattern in the text
int last_ind = q_indices.Dequeue();
Console.Write(" " + (last_ind - (pat_len - 1)));
}
Console.WriteLine();
}
// Driver code
static void Main(string[] args)
{
// Passing the Text
string text = "Welcome to Geeks for Geeks";
string pattern = "Geeks";
// Function call
pattern_search(text, pattern);
}
}
JavaScript
// Using a 256 sized array of hash sets
const structuredText = Array(256).fill().map(() => new Set());
// Function to perform the hashing
function stringSearch(st) {
// Structure the text. It will be helpful in pattern searching
for (let i = 0; i < st.length; i++) {
// Insert every index to the hash set using character ASCII
structuredText[st.charCodeAt(i)].add(i);
}
}
// Function to search the pattern
function patternSearch(st, pattern) {
stringSearch(st);
// Queue contain the indices
const indicesQueue = [];
for (const ind of structuredText[pattern.charCodeAt(0)]) {
indicesQueue.push(ind);
}
// Pattern length
const patLen = pattern.length;
for (let i = 1; i < patLen; i++) {
const ch = pattern.charCodeAt(i);
let qSize = indicesQueue.length;
// The queue contains the number of occurrences of the previous character
// Traverse the queue for qSize times
// Check the next character of the pattern found or not
while (qSize--) {
const ind = indicesQueue.shift();
if (structuredText[ch].has(ind + 1)) {
indicesQueue.push(ind + 1);
}
}
}
console.log("Pattern found at indexes:");
while (indicesQueue.length > 0) {
// lastInd is the last index of the pattern in the text
const lastInd = indicesQueue.shift();
console.log(" ", lastInd - (patLen - 1));
}
console.log();
}
// Driver code
const text = "Welcome to Geeks for Geeks";
const pattern = "Geeks";
// Function call
patternSearch(text, pattern);
OutputPattern found at indexes: 21 11
Time Complexity: O(N * logK), where K is the maximum occurrence of any character
Auxiliary Space: O(d), d represents a 256 sized array of unordered_set
Similar Reads
What is Pattern Searching ?
Pattern searching in Data Structures and Algorithms (DSA) is a fundamental concept that involves searching for a specific pattern or sequence of elements within a given data structure. This technique is commonly used in string matching algorithms to find occurrences of a particular pattern within a
5 min read
Pattern Searching
Pattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
Search strings with the help of given pattern in an Array of strings
Prerequisite: Trie | (Insert and Search) Given an array of strings words[] and a partial string str, the task is to find the strings of the given form str from the given array of string. A partial string is a string with some missing characters. For Example: "..ta", is a string of length 4 ending wi
12 min read
Pattern Searching using C++ library
Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function that prints all occurrences of pat[] in txt[]. You may assume that n > m.Examples: Input : txt[] = "geeks for geeks" pat[] = "geeks" Output : Pattern found at index 0 Pattern found at index 10 Input : txt[] = "aaaa" pat[] = "aa"
3 min read
Naive algorithm for Pattern Searching
Given text string with length n and a pattern with length m, the task is to prints all occurrences of pattern in text. Note: You may assume that n > m. Examples:Â Input: Â text = "THIS IS A TEST TEXT", pattern = "TEST"Output: Pattern found at index 10 Input: Â text = Â "AABAACAADAABAABA", pattern =
6 min read
Pattern Searching using Suffix Tree
Given a text txt[0..n-1] and a pattern pat[0..m-1], write a function search(char pat[], char txt[]) that prints all occurrences of pat[] in txt[]. You may assume that n > m. Preprocess Pattern or Preprocess Text? We have discussed the following algorithms in the previous posts: KMP Algorithm Rabi
4 min read
Z algorithm (Linear time pattern searching Algorithm)
This algorithm efficiently locates all instances of a specific pattern within a text in linear time. If the length of the text is "n" and the length of the pattern is "m," then the total time taken is O(m + n), with a linear auxiliary space. It is worth noting that the time and auxiliary space of th
13 min read
KMP Algorithm for Pattern Searching
Given two strings txt and pat, the task is to return all indices of occurrences of pat within txt. Examples:Input: txt = "abcab", pat = "ab"Output: [0, 3]Explanation: The string "ab" occurs twice in txt, first occurrence starts from index 0 and second from index 3.Input: txt= "aabaacaadaabaaba", pat
14 min read
Suffix Tree Application 2 - Searching All Patterns
Given a text string and a pattern string, find all occurrences of the pattern in string. Few pattern searching algorithms (KMP, Rabin-Karp, Naive Algorithm, Finite Automata) are already discussed, which can be used for this check. Here we will discuss the suffix tree based algorithm. In the 1st Suff
15+ min read
Recursive function to do substring search
Given a text txt[] and a pattern pat[], write a recursive function "contains(char pat[], char txt[])" that returns true if pat[] is present in txt[], otherwise false. Examples: 1) Input: txt[] = "THIS IS A TEST TEXT" pat[] = "TEST" Output: true 2) Input: txt[] = "geeksforgeeks" pat[] = "quiz" Output
9 min read