📌  相关文章
📜  检查给定的单词是否存在于字符串

📅  最后修改于: 2021-10-27 08:42:26             🧑  作者: Mango

给定一个大字符串和一组小字符串,它们的长度都小于大字符串。任务是创建一个布尔数组,其中每个布尔值表示小字符串数组中该索引处的小字符串是否包含在大字符串。

注意:您不能使用语言内置的字符串匹配方法。

例子:

方法:天真的方法
解决这个问题的一个简单方法是遍历所有的小字符串,通过遍历大字符串的字符并用几个循环将它们与给定的小字符串的字符进行比较来检查它们中的每一个是否包含在大字符串。

下面是上述方法的实现:

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 multiStringSearch
vector 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 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 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 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


输出 :

true false true true false true false

时间复杂度: O(b * n * s),其中 b 是大串的长度,n 是小字符串的数量,s 是最长的小字符串的长度。

辅助空间: O(n)

方法:使用后缀树
构建一个包含所有大字符串后缀的 Suffix-trie 数据结构。然后,遍历所有小字符串并检查它们中的每一个是否都包含在您创建的数据结构中。

下面是上述方法的实现:

// 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 TrieNode
class 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 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 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 code
int 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;
}

输出 :

true false true true false true false

时间复杂度: O(b*b + n * s),其中 b 是大串的长度,n 是小字符串的数量,s 是最长的小字符串的长度。
辅助空间: O(b*2 + n)

方法:使用 Trie
尝试构建一个包含所有小字符串的 trie。然后,通过迭代的大串的字符,并检查大字符串的任何部分是包含在已创建线索的字符串。

下面是上述方法的实现:

// 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 TrieNode
class 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 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* containedStrings);
  
// Function to the multiStringSearch
vector 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 findSmallStringsIn
void 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 code
int 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;
}

输出 :

true false true true false true false

时间复杂度: O(n*s + b * s),其中 b 是大串的长度,n 是小字符串的数量,s 是最长的小字符串的长度。
辅助空间: O(ns)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程