Check if given words are present in a string

• Difficulty Level : Hard
• Last Updated : 04 Jun, 2022

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++

 // Find the small string at that index in the array of// small strings is contained in the big string#include using namespace std;bool isInBigString(string bigString, string smallString);bool isInBigStringHelper(string bigString, string smallString, int startIdx); // Function to the multiStringSearchvector multiStringSearch(string bigString,                          vector smallStrings){    vector solution;     // iterate in the smallString    for (string smallString : smallStrings) {         // calling the isInBigString Function        solution.push_back(isInBigString(bigString, smallString));    }    return solution;} // Function to the bigStringbool 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 bigStringbool 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 codeint main(int argc, char* argv[]){    // initialize string    string str = "this is a big string";     // initialize vector string     vector substr = { "this", "yo", "is", "a",                        "bigger", "string", "kappa" };     // Function call    vector 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;}

Python3

 # Find the small string at that index in the array of# small strings is contained in the big string # Helper Function to the Finding bigStringdef 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 bigStringdef 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 multiStringSearchdef multiStringSearch(bigString, smallStrings):    solution = []     # iterate in the smallString    for smallString in smallStrings:        # calling the isInBigString Function        solution.append(isInBigString(bigString, smallString))    return solution # Driver codeif __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

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:

CPP

 // Find the small string at that index in the array of// small strings is contained in the big string#include using namespace std;// Blueprint of the TrieNodeclass TrieNode {public:     // Declaring children to be of type    // key will be of char type and mapped value will    // be of TrieNode type    unordered_map children;}; // Blueprint of the ModifiedSuffixTrieclass 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 multiStringSearchvector multiStringSearch(string bigString, vector smallStrings){    ModifiedSuffixTrie modifiedSuffixTrie(bigString);    vector solution;     // iterate in the smallString    for (string smallString : smallStrings) {        solution.push_back(modifiedSuffixTrie.contains(smallString));    }    return solution;} // Driver codeint main(int argc, char* argv[]){    // initialize string    string str = "this is a big string";     // initialize vector string    vector substr = { "this", "yo", "is", "a",                        "bigger", "string", "kappa" };     // Function call    vector 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;}

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:

CPP

 // Find the small string at that index in the array of// small strings is contained in the big string#include using namespace std; // Blueprint of the TrieNodeclass TrieNode {public:     // Declaring children to be of type    // key will be of char type and mapped value will    // be of TrieNode type    unordered_map children;    string word;}; // Blueprint of the Trieclass 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 functionvoid findSmallStringsIn(string str, int startIdx, Trie* trie,                   unordered_map* containedStrings); // Function to the multiStringSearchvector multiStringSearch(string bigString, vector smallStrings){    Trie* trie = new Trie();     // iterate in the smallString    for (string smallString : smallStrings) {        trie->insert(smallString);    }     // Declaring containedStrings to be of type    // key will be of string type and mapped value will    // be of boolean type    unordered_map containedStrings;     // iterate in the bigString    for (int i = 0; i < bigString.length(); i++) {        findSmallStringsIn(bigString, i, trie, &containedStrings);    }     vector solution;     // iterate in the smallString    for (string smallString : smallStrings) {        solution.push_back(containedStrings.find(smallString)                                   != containedStrings.end());    }    return solution;} // Function to findSmallStringsInvoid findSmallStringsIn(string str, int startIdx,    Trie* trie, unordered_map* 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 codeint main(int argc, char* argv[]){    // initialize string    string str = "this is a big string";     // initialize vector string    vector substr = { "this", "yo", "is", "a",                         "bigger", "string", "kappa" };     // Function call    vector 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;}

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)

Python3 approach using find() method

Python3

 # python code to check whether a word is present in a string or notbigString = "this is a big string"smallStrings = ["this", "yo", "is", "a", "bigger", "string", "kappa"]x = []# find() - returns position of specified value or else returns -1for i in smallStrings:  if(bigString.find(i) != -1):    x.append(True)  else:    x.append(False)print(x)

Output

[True, False, True, True, False, True, False]

My Personal Notes arrow_drop_up