首页 > 解决方案 > 在字符串中查找多个子字符串时遇到问题

问题描述

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

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 相反的方法会起作用,但不确定是否存在。

标签: c++stringsubstring

解决方案


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

但是,由于您想将作为整个单词的子字符串与较大单词中的子字符串区分开来,您需要在比较它们之前解析字符串以确定整个单词。

您可以使用std::string::find_first_of()andstd::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;
}

或者,您可以将整个单词提取到 a 中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);
}

推荐阅读