Check if given words are present in a string

Given a big string and an array of small strings, all of which are smaller in length than the big string. The task is to create an array of booleans, where each boolean represents whether the small string at that index in the array of small strings is contained in the big string.

Note : that you can’t use language-built-in string-matching methods.

Examples:

Input : bigString = “this is a big string”, smallStrings = [“this”, “yo”, “is”, “a”, “bigger”, “string”, “kappa”]
Output : [true, false, true, true, false, true, false]

Input : bigString = “Mary goes to the shopping center every week.”, smallStrings = [“to”, “Mary”, “centers”, “shop”, “shopping”, “string”, “kappa”]
Output : [true, true, false, true, true, false, false]



Approach : Naive Approach
A simple way to solve this problem is to iterate through all of the small strings, checking if each of them is contained in the big string by iterating through the big string’s characters and comparing them to the given small string’s characters with a couple of loops.

Below is the implementation of the above approach:

C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// Find the small string at that index in the array of
// small strings is contained in the big string
#include <bits/stdc++.h>
using namespace std;
bool isInBigString(string bigString, string smallString);
bool isInBigStringHelper(string bigString, string smallString, int startIdx);
  
// Function to the multiStringSearch
vector<bool> multiStringSearch(string bigString,
                          vector<string> smallStrings)
{
    vector<bool> solution;
  
    // iterate in the smallString
    for (string smallString : smallStrings) {
  
        // calling the isInBigString Function
        solution.push_back(isInBigString(bigString, smallString));
    }
    return solution;
}
  
// Function to the bigString
bool isInBigString(string bigString, string smallString)
{
    // iterate in the bigString
    for (int i = 0; i < bigString.length(); i++) {
  
        // Check if length of smallString + i is greater than
        // the length of bigString
        if (i + smallString.length() > bigString.length()) {
            break;
        }
  
        // call the function isInBigStringHelper
        if (isInBigStringHelper(bigString, smallString, i)) {
            return true;
        }
    }
    return false;
}
  
// Helper Function to the Finding bigString
bool isInBigStringHelper(string bigString, string smallString, int startIdx)
{
    // Initialize leftBigIdx and rightBigIdx and leftSmallIdx variables
    int leftBigIdx = startIdx;
    int rightBigIdx = startIdx + smallString.length() - 1;
    int leftSmallIdx = 0;
    int rightSmallIdx = smallString.length() - 1;
  
  
    // Iterate until leftBigIdx variable reaches less 
    // than or equal to rightBigIdx
    while (leftBigIdx <= rightBigIdx) {
  
        // Check if bigString[leftBigIdx] is not equal
        // to smallString[leftSmallIdx] or Check if 
        // bigString[rightBigIdx] is not equal to 
        // smallString[rightSmallIdx] than return false
        // otherwise increment leftBigIdx and leftSmallIdx
        // decrement rightBigIdx and rightSmallIdx
        if (bigString[leftBigIdx] != smallString[leftSmallIdx] || 
            bigString[rightBigIdx] != smallString[rightSmallIdx]) {
            return false;
        }
  
        leftBigIdx++;
        rightBigIdx--;
        leftSmallIdx++;
        rightSmallIdx--;
    }
  
    return true;
}
  
// Driver code
int main(int argc, char* argv[])
{
    // initialize string
    string str = "this is a big string";
  
    // initialize vector string
  
    vector<string> substr = { "this", "yo", "is", "a"
                        "bigger", "string", "kappa" };
  
    // Function call
    vector<bool> ans = multiStringSearch(str, substr);
  
    // Print answers
    for (int i = 0; i < ans.size(); i++) {
  
        // Check if ans[i] is equal to 1
        // then Print true otherwise print false
        if (ans[i] == 1) {
            cout << "true"
                 << " ";
        }
        else {
            cout << "false"
                 << " ";
        }
    }
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Find the small string at that index in the array of
# small strings is contained in the big string
  
# Helper Function to the Finding bigString
def isInBigStringHelper(bigString,smallString,startIdx):
      
    # Initialize leftBigIdx and rightBigIdx and leftSmallIdx variables
    leftBigIdx = startIdx
    rightBigIdx = startIdx + len(smallString) - 1
    leftSmallIdx = 0
    rightSmallIdx = len(smallString) - 1
  
    # Iterate until leftBigIdx variable reaches less 
    # than or equal to rightBigIdx
    while (leftBigIdx <= rightBigIdx):
          
        # Check if bigString[leftBigIdx] is not equal
        # to smallString[leftSmallIdx] or Check if 
        # bigString[rightBigIdx] is not equal to 
        # smallString[rightSmallIdx] than return false
        # otherwise increment leftBigIdx and leftSmallIdx
        # decrement rightBigIdx and rightSmallIdx
        if (bigString[leftBigIdx] != smallString[leftSmallIdx] or 
            bigString[rightBigIdx] != smallString[rightSmallIdx]):
            return False
  
        leftBigIdx += 1
        rightBigIdx -= 1
        leftSmallIdx += 1
        rightSmallIdx -= 1
    return True
  
# Function to the bigString
def isInBigString(bigString, smallString):
      
    # iterate in the bigString
    for i in range(len(bigString)):
          
        # Check if length of smallString + i is greater than
        # the length of bigString
        if (i + len(smallString) > len(bigString)):
            break
  
        # call the function isInBigStringHelper
        if (isInBigStringHelper(bigString, smallString, i)):
            return True
    return False
  
# Function to the multiStringSearch
def multiStringSearch(bigString, smallStrings):
    solution = []
  
    # iterate in the smallString
    for smallString in smallStrings:
        # calling the isInBigString Function
        solution.append(isInBigString(bigString, smallString))
    return solution
  
# Driver code
if __name__ == '__main__':
    # initialize string
    str1 = "this is a big string"
  
    # initialize vector string
  
    substr = ["this", "yo", "is", "a","bigger", "string", "kappa"]
  
    # Function call
    ans = multiStringSearch(str1, substr)
  
    # Print answers
    for i in range(len(ans)):
        # Check if ans[i] is equal to 1
        # then Print true otherwise print false
        if (ans[i] == 1):
            print("true",end = " ")
        else:
            print("false",end = " ")
  
# This code is contributed by Bhupendra_Singh

chevron_right


Output :

true false true true false true false

Time Complexity : O(b * n * s), where b is the length of the bigstring and n is the number of small strings and s is the length of longest small string.

Auxiliary Space : O(n)

Approach : Using Suffix Trie
Build a Suffix-trie data structure containing all of the big string’s suffixes. Then, iterate through all of the small strings and check if each of them is contained in the data structure you have created.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Find the small string at that index in the array of
// small strings is contained in the big string
#include <bits/stdc++.h>
using namespace std;
// Blueprint of the TrieNode
class TrieNode {
public:
  
    // Declaring children to be of <char, TrieNode> type
    // key will be of char type and mapped value will
    // be of TrieNode type
    unordered_map<char, TrieNode*> children;
};
  
// Blueprint of the ModifiedSuffixTrie
class ModifiedSuffixTrie {
public:
    TrieNode* root;
    ModifiedSuffixTrie(string str)
    {
        this->root = new TrieNode();
  
        // Function call 
        this->populateModifiedSuffixTrieFrom(str); 
    }
  
    void populateModifiedSuffixTrieFrom(string str)
    {
        // iterate in the length of String
        for (int i = 0; i < str.length(); i++) {
  
            // Function call 
            this->insertSubstringStartingAt(i, str); 
        }
    }
  
    void insertSubstringStartingAt(int i, string str)
    {
        TrieNode* node = this->root;
  
        // iterate in the length of String
        for (int j = i; j < str.length(); j++) {
  
            // initialize char as a letter
            // put the value of str[j] in letter
            char letter = str[j];
  
            // Check if letter is is equal to endnode or not
            if (node->children.find(letter) == node->children.end()) {
                TrieNode* newNode = new TrieNode();
                node->children.insert({ letter, newNode });
            }
            node = node->children[letter];
        }
    }
  
    bool contains(string str)
    {
        TrieNode* node = this->root;
  
        // iterate in the String
        for (char letter : str) {
  
            // Check if letter is is equal to endnode or not
            if (node->children.find(letter) == node->children.end()) {
                return false;
            }
            node = node->children[letter];
        }
        return true;
    }
};
  
// Function to the multiStringSearch
vector<bool> multiStringSearch(string bigString, vector<string> smallStrings)
{
    ModifiedSuffixTrie modifiedSuffixTrie(bigString);
    vector<bool> solution;
  
    // iterate in the smallString
    for (string smallString : smallStrings) {
        solution.push_back(modifiedSuffixTrie.contains(smallString));
    }
    return solution;
}
  
// Driver code
int main(int argc, char* argv[])
{
    // initialize string
    string str = "this is a big string";
  
    // initialize vector string
    vector<string> substr = { "this", "yo", "is", "a"
                        "bigger", "string", "kappa" };
  
    // Function call
    vector<bool> ans = multiStringSearch(str, substr);
  
    // Print answers
    for (int i = 0; i < ans.size(); i++) {
  
        // Check if ans[i] is equal to 1
        // then Print true otherwise print false
        if (ans[i] == 1) {
            cout << "true"
                 << " ";
        }
        else {
            cout << "false"
                 << " ";
        }
    }
    return 0;
}

chevron_right


Output :

true false true true false true false

Time Complexity : O(b*b + n * s), where b is the length of the bigstring and n is the number of small strings and s is the length of longest small string.
Auxiliary Space : O(b*2 + n)

Approach : Using Trie
Try building a trie containing all of the small strings. Then, iterate through the big string’s characters and check if any part of the big string is a string contained in the trie you have created.

Below is the implementation of the above approach:

filter_none

edit
close

play_arrow

link
brightness_4
code

// Find the small string at that index in the array of
// small strings is contained in the big string
#include <bits/stdc++.h>
using namespace std;
  
// Blueprint of the TrieNode
class TrieNode {
public:
  
    // Declaring children to be of <char, TrieNode> type
    // key will be of char type and mapped value will
    // be of TrieNode type
    unordered_map<char, TrieNode*> children;
    string word;
};
  
// Blueprint of the Trie
class Trie {
public:
    TrieNode* root;
    char endSymbol;
    Trie()
    {
        this->root = new TrieNode();
        this->endSymbol = '*';
    }
  
    // function to insert string
    void insert(string str)
    {
        TrieNode* current = this->root;
  
        // iterate in the length of String
        for (int i = 0; i < str.length(); i++) {
  
            // initialize char as a letter
            // put the value of str[i] in letter
            char letter = str[i];
  
            // Check if letter is is equal to endnode or not
            if (current->children.find(letter) == current->children.end()) {
                TrieNode* newNode = new TrieNode();
                current->children.insert({ letter, newNode });
            }
            current = current->children[letter];
        }
        current->children.insert({ this->endSymbol, NULL });
        current->word = str;
    }
};
  
// define a findSmallStringsIn function
void findSmallStringsIn(string str, int startIdx, Trie* trie, 
                   unordered_map<string, bool>* containedStrings);
  
// Function to the multiStringSearch
vector<bool> multiStringSearch(string bigString, vector<string> smallStrings)
{
    Trie* trie = new Trie();
  
    // iterate in the smallString
    for (string smallString : smallStrings) {
        trie->insert(smallString);
    }
  
    // Declaring containedStrings to be of <string, bool> type
    // key will be of string type and mapped value will
    // be of boolean type
    unordered_map<string, bool> containedStrings;
  
    // iterate in the bigString
    for (int i = 0; i < bigString.length(); i++) {
        findSmallStringsIn(bigString, i, trie, &containedStrings);
    }
  
    vector<bool> solution;
  
    // iterate in the smallString
    for (string smallString : smallStrings) {
        solution.push_back(containedStrings.find(smallString) 
                                   != containedStrings.end());
    }
    return solution;
}
  
// Function to findSmallStringsIn
void findSmallStringsIn(string str, int startIdx, 
    Trie* trie, unordered_map<string, bool>* containedStrings)
{
    TrieNode* currentNode = trie->root;
  
    // iterate the length of the string
    for (int i = startIdx; i < str.length(); i++) {
  
        // Check if letter is is equal to endnode or not
        if (currentNode->children.find(str[i]) ==
                          currentNode->children.end()) {
            break;
        }
        currentNode = currentNode->children[str[i]];
  
        if (currentNode->children.find(trie->endSymbol) != 
                             currentNode->children.end()) {
            containedStrings->insert({ currentNode->word, true });
        }
    }
}
  
// Driver code
int main(int argc, char* argv[])
{
    // initialize string
    string str = "this is a big string";
  
    // initialize vector string
    vector<string> substr = { "this", "yo", "is", "a",
                         "bigger", "string", "kappa" };
  
    // Function call
    vector<bool> ans = multiStringSearch(str, substr);
  
    // Print answers
    for (int i = 0; i < ans.size(); i++) {
  
        // Check if ans[i] is equal to 1
        // then Print true otherwise print false
        if (ans[i] == 1) {
            cout << "true"
                 << " ";
        }
        else {
            cout << "false"
                 << " ";
        }
    }
    return 0;
}

chevron_right


Output :

true false true true false true false

Time Complexity : O(n*s + b * s), where b is the length of the bigstring and n is the number of small strings and s is the length of longest small string.
Auxiliary Space : O(ns)

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.



Improved By : bgangwar59