在字符串中查找多个子字符串时遇到问题

时间:2019-12-02 05:27:39

标签: c++ string substring

我正在尝试编写一个程序,每次在字符串中找到子字符串时,该程序都会比较两个字符串(字符串和子字符串)和激励。但是,使用标准:

if(str.find(substr) != string::npos)
{
count++;
}

我遇到一个问题,如果子字符串在字符串中出现多次,则它只会递增一次。因此,如果字符串是“ test test test test”,而子字符串是“ test”,则计数最终只能是1而不是4。

解决此问题的最佳方法是什么?

*上下文注释:

1)在某一点上,我正在逐个字符地检查字符串是否匹配,但是当我遇到一些单词中的单词较小的问题时,不得不将其废弃。

示例:“ is”将在单词“ this”之内,等等

2)这是用于较大的程序,它接受两个向量。对于每个元素,第一个向量都有一个字符串,这些元素是用户键入的句子(作用于以上示例中的主字符串)。第二个向量将所有句子中的每个单词输入第一个向量(在上面的示例中用作子字符串)。不知道这点是否重要,但我想我会把它扔在那里

示例:

vector<string> str {this is line one, this is line two, this is line three};
vector<string> substr {is, line, one, this, three, two};

3)我在想是否可以做一些与!= string :: npos相反的方法,但是不确定是否存在。

1 个答案:

答案 0 :(得分:0)

您需要循环查找给定字符串中所有子字符串的出现。

但是,由于要区分完整单词的子字符串和较大单词中的子字符串,因此需要在比较它们之前分析字符串以确定整个单词。

您可以使用std::string::find_first_of()std::string::find_first_not_of()查找所需分隔符(空格,标点符号等)之间每个完整单词的开头和结尾索引。您可以使用std::string::compare()将这两个索引之间的子字符串与所需的子字符串进行比较。例如:

#include <string>

const std::string delims = ",. ";

size_t countWord(const std::string &str, const std::string &word)
{
    std::string::size_type start = 0, end;
    size_t count = 0;

    while ((start = str.find_first_not_of(delims, start)) != std::string::npos)
    {
        end = str.find_first_of(delims, start+1);
        if (end == std::string::npos)
        {
            if (str.compare(start, str.size()-start, word) == 0)
                ++count;

            break;
        }

        if (str.compare(start, end-start, word) == 0)
            ++count;

        start = end + 1;
    }

    return count;
}

或者,您可以将整个单词提取到std::vector中,然后使用std::count()计算与子字符串匹配的元素个数。例如:

#include <string>
#include <vector>
#include <algorithm>

const std::string delims = ",. ";

size_t countWord(const std::string &str, const std::string &word)
{
    std::vector<std::string> vec;
    std::string::size_type start = 0, end;

    while ((start = str.find_first_not_of(delims, start)) != string::npos)
    {
        end = str.find_first_of(delims, start+1);
        if (end == std::string::npos)
        {
            vec.push_back(str.substr(start));
            break;
        }

        vec.push_back(str.substr(start, end-start));

        start = end + 1;
    }

    return std::count(vec.begin(), vec.end(), word);
}