C++ C++;-检查数组中所有值的字符串

C++ C++;-检查数组中所有值的字符串,c++,find,C++,Find,我有一些来自Vision API的解析文本,我正在使用关键字对其进行过滤,如下所示: if (finalTextRaw.find("File") != finalTextRaw.npos) { LogMsg("Found Menubar"); } 例如,如果在字符串finalTextRaw中的任意位置找到关键字“File”,则该功能将中断,并打印日志消息 这种方法非常可靠。但我只是以这种方式做了一堆if-else-if语句,效率很低。随着

我有一些来自Vision API的解析文本,我正在使用关键字对其进行过滤,如下所示:

    if (finalTextRaw.find("File") != finalTextRaw.npos)
{
    LogMsg("Found Menubar");
}
例如,如果在字符串
finalTextRaw
中的任意位置找到关键字“File”,则该功能将中断,并打印日志消息

这种方法非常可靠。但我只是以这种方式做了一堆if-else-if语句,效率很低。随着我发现更多需要过滤的单词,我宁愿效率更高一点。相反,我现在从配置文件中获取一个字符串,然后将该字符串解析为一个数组:

    string filterWords = GetApp()->GetFilter();
    std::replace(filterWords.begin(), filterWords.end(), ',', ' ');  ///replace ',' with ' '
    vector<int> array;
    stringstream ss(filterWords);
    int temp;
    while (ss >> temp)
        array.push_back(temp); ///create an array of filtered words
当然,这种语法不起作用,而且肯定比这更复杂,但希望您能理解:如果我的数组中的任何单词出现在该字符串中的任何位置,那么应该忽略该字符串,并打印一条日志消息


你知道我该如何设计这样一个函数吗?我猜这将需要某种循环。

你可以使用一种基本的强力循环:

unsigned int quantity_words = array.size();
for (unsigned int i = 0; i < quantity_words; ++i)
{
   std::string word = array[i];
   if (finalTextRaw.find(word) != std::string::npos)
   {
        // word is found.
        // do stuff here or call a function.
        break;  // stop the loop.
   }
}
unsigned int quantity_words=array.size();
for(无符号整数i=0;i
上面的循环获取数组中的每个单词,并在
finalTextRaw
中搜索该单词

使用一些
std
算法有更好的方法。我将把这个留给其他答案

编辑1:地图和关联
上面的代码让我很烦恼,因为通过
finalTextRaw
字符串的过程太多了

还有一个想法:

  • 使用
    finalTextRaw
    中的单词创建一个
    std::set
  • 对于
    数组中的每个单词,检查集合中是否存在。
    这减少了搜索的数量(就像搜索一棵树)

  • 您还应该研究在
    数组中创建一组单词,并找到这两组单词之间的交点。

    您可以使用基本的强力循环:

    unsigned int quantity_words = array.size();
    for (unsigned int i = 0; i < quantity_words; ++i)
    {
       std::string word = array[i];
       if (finalTextRaw.find(word) != std::string::npos)
       {
            // word is found.
            // do stuff here or call a function.
            break;  // stop the loop.
       }
    }
    
    unsigned int quantity_words=array.size();
    for(无符号整数i=0;i
    上面的循环获取数组中的每个单词,并在
    finalTextRaw
    中搜索该单词

    使用一些
    std
    算法有更好的方法。我将把这个留给其他答案

    编辑1:地图和关联
    上面的代码让我很烦恼,因为通过
    finalTextRaw
    字符串的过程太多了

    还有一个想法:

  • 使用
    finalTextRaw
    中的单词创建一个
    std::set
  • 对于
    数组中的每个单词,检查集合中是否存在。
    这减少了搜索的数量(就像搜索一棵树)

  • 您还应该研究在
    数组中创建一组单词,并找到这两组单词之间的交点。

    借用Thomas的答案,ranged for循环提供了一个简洁的解决方案:

    for (const auto &word : words)
    {
       if (finalTextRaw.find(word) != std::string::npos)
       {
            // word is found.
            // do stuff here or call a function.
            break;  // stop the loop.
       }
    }
    

    借用Thomas的答案,远程for循环提供了一个简洁的解决方案:

    for (const auto &word : words)
    {
       if (finalTextRaw.find(word) != std::string::npos)
       {
            // word is found.
            // do stuff here or call a function.
            break;  // stop the loop.
       }
    }
    

    正如托马斯所指出的,最有效的方法是将两个文本分割成一个单词列表。然后使用
    std::set_intersection
    查找两个列表中的匹配项。您可以使用
    std::vector
    ,只要它已排序。最终得到的是
    O(n*log(n))
    (n=max words),而不是
    O(n*m)

    将句子拆分为单词:

    auto split(std::string_view sentence) {
        auto result = std::vector<std::string>{};
        auto stream = std::istringstream{sentence.data()};    
    
        std::copy(std::istream_iterator<std::string>(stream),
                  std::istream_iterator<std::string>(), std::back_inserter(result));
    
        return result;
    }
    

    请注意,这在处理大量或未定义的单词时是有意义的。如果您知道这些限制,您可能希望使用更简单的解决方案(由其他答案提供)。

    正如Thomas所指出的,最有效的方法是将两个文本拆分为一个单词列表。然后使用
    std::set_intersection
    查找两个列表中的匹配项。您可以使用
    std::vector
    ,只要它已排序。最终得到的是
    O(n*log(n))
    (n=max words),而不是
    O(n*m)

    将句子拆分为单词:

    auto split(std::string_view sentence) {
        auto result = std::vector<std::string>{};
        auto stream = std::istringstream{sentence.data()};    
    
        std::copy(std::istream_iterator<std::string>(stream),
                  std::istream_iterator<std::string>(), std::back_inserter(result));
    
        return result;
    }
    

    请注意,这在处理大量或未定义的单词时是有意义的。如果您知道限制,您可能希望使用更简单的解决方案(由其他答案提供)。

    啊,似乎我遇到了
    错误C2440“初始化”:无法从“\u Ty”转换为“std::basic\u string”
    。我认为在这种情况下,这意味着我的
    数组实际上没有被定义?我想我不能确定我的第一段代码首先是否正确生成了数组。@肖邦我们需要查看您的实际代码才能回答这个问题。啊,似乎我遇到了
    错误C2440“初始化”:无法从“\Ty”转换为“std::basic\u string”
    。我认为在这种情况下,这意味着我的
    数组实际上没有被定义?我想我不能确定我的第一段代码首先是否正确生成了数组。@肖邦我们需要查看您的实际代码才能回答这个问题。您知道过滤器中的字数吗?在原始文本中?检查你知道过滤器中的字数吗?在原始文本中?检查