如何在字符串中搜索多个子字符串

时间:2017-05-16 13:51:33

标签: c++ string optimization substring time-complexity

我需要检查一个短字符串,以查找与子字符串列表匹配的字符串。目前,我这样做如下所示(working code on ideone

bool ContainsMyWords(const std::wstring& input)
{
    if (std::wstring::npos != input.find(L"white"))
        return true;
    if (std::wstring::npos != input.find(L"black"))
        return true;
    if (std::wstring::npos != input.find(L"green"))
        return true;
    // ...
    return false;
}


int main() {
  std::wstring input1 = L"any text goes here";
  std::wstring input2 = L"any text goes here black";

  std::cout << "input1 " << ContainsMyWords(input1) << std::endl;
  std::cout << "input2 " << ContainsMyWords(input2) << std::endl;
  return 0;
}

我有10-20个子串,我需要匹配输入。我的目标是优化代码以提高CPU利用率并减少平均情况下的时间复杂度。我以10 Hz的速率接收输入字符串,突发到10 kHz(这是我担心的)。

agrep库,源代码用C编写,我想知道C ++中是否有标准的等价物。从快速看一下,将它与我所拥有的相结合可能有点困难(但可行)。

有没有更好的方法将输入字符串与C ++中的一组预定义子字符串进行匹配?

2 个答案:

答案 0 :(得分:1)

如果使用以下正则表达式,最好的方法是使用正则表达式搜索:

"(white)|(black)|(green)"

这样,只有一次遍历字符串,如果找到"white"子字符串(以及起点和终点)的匹配,则会进入第1组,如果匹配的话,则在第2组中"black"子字符串(以及起点和终点),如果匹配"green"子字符串,则在第3组中。当你得到的时候,从第0组到比赛结束的位置,你可以开始一个新的搜索来寻找更多的匹配,并且一切都在字符串上传递!!!

答案 1 :(得分:-1)

你可以使用一个大的if而不是几个if语句。但是,带有std::any_of的Nathan的Oliver解决方案比制作子串static的数组更快(因此它们不会被反复重新创建),如图所示下方。

bool ContainsMyWordsNathan(const std::wstring& input)
{
    // do not forget to make the array static!
    static std::wstring keywords[] = {L"white",L"black",L"green", ...};
    return std::any_of(std::begin(keywords), std::end(keywords),
      [&](const std::wstring& str){return input.find(str) != std::string::npos;});
}

PS:正如Algorithm to find multiple string matches中讨论的那样:

&#34; grep&#34; family以非常有效的方式实现多字符串搜索。如果您可以将它们用作外部程序,请执行此操作。