给定一个大字符串和一组小字符串,它们的长度都小于大字符串。任务是创建一个布尔数组,其中每个布尔值表示小字符串数组中该索引处的小字符串是否包含在大字符串。
注意:您不能使用语言内置的字符串匹配方法。
例子:
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]
方法:天真的方法
解决这个问题的一个简单方法是遍历所有的小字符串,通过遍历大字符串的字符并用几个循环将它们与给定的小字符串的字符进行比较来检查它们中的每一个是否包含在大字符串。
下面是上述方法的实现:
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 现场工作专业课程和学生竞争性编程现场课程。