为C++中的子字符串的所有事件搜索字符串

为C++中的子字符串的所有事件搜索字符串,c++,string,C++,String,编写一个函数countMatches,用于搜索给定字符串中的子字符串,并返回子字符串在字符串中出现的次数 我已经被困在这个问题上6个多小时了,如果能得到任何帮助,我将不胜感激。我真的很想更好地理解这一点 int countMatches(string str, string comp) { int small = comp.length(); int large = str.length(); int count = 0; // If string is emp

编写一个函数countMatches,用于搜索给定字符串中的子字符串,并返回子字符串在字符串中出现的次数

我已经被困在这个问题上6个多小时了,如果能得到任何帮助,我将不胜感激。我真的很想更好地理解这一点

int countMatches(string str, string comp)
{
    int small = comp.length();
    int large = str.length();
    int count = 0;

    // If string is empty
    if (small == 0 || large == 0) {
        return -1;
    }

    // Increment i over string length
    for (int i = 0; i < small; i++) {
        // Output substring stored in string
        for (int j = 0; j < large; j++) {
            if (comp.substr(i, small) == str.substr(j, large)) {
                count++;
            }
        }
    }

    cout << count << endl;
    return count;
}

当我从main调用这个函数时,用countMatchesHello,Hello;我得到5的输出。这是完全错误的,因为它应该返回1。我只想知道我在这里做错了什么,这样我就不会重复错误并真正理解我在做什么。

我明白了。我不需要嵌套的for循环,因为我只是将次要字符串与该字符串的字符串进行比较。它还消除了获取第一个字符串的子字符串的需要。所以。。。对那些感兴趣的人来说,应该是这样的:

int countMatches(string str, string comp)
{
    int small = comp.length();
    int large = str.length();
    int count = 0;

    // If string is empty
    if (small == 0 || large == 0) {
        return -1;
    }

    // Increment i over string length
    for (int i = 0; i < large; i++) {
        // Output substring stored in string
        if (comp == str.substr(i, small)) {
            count++;
        }
    }

    cout << count << endl;
    return count;
}

函数的问题在于您正在检查:

Hello是Hello的子串 ello是ello的子串 llo是llo的子串 ... 当然,在这种情况下,这匹配5次

您真正需要的是:

对于str的每个位置i 检查从i开始且长度=comp.size的str的子字符串是否为comp.size。 下面的代码应该正好做到这一点:

size_t countMatches(const string& str, const string& comp)
{
    size_t count = 0;
    for (int j = 0; j < str.size()-comp.size()+1; j++)
         if (comp == str.substr(j, comp.size()))
              count++;
    return count;
}

通常的方法是就地搜索:

std::string::size_type pos = 0;
int count = 0;
for (;;) {
    pos = large.find(small, pos);
    if (pos == std::string::npos)
        break;
    ++count;
    ++pos;
}

如果您不关心重叠匹配,也就是说,在字符串llll中查找ll的所有匹配项,则可以对其进行调整。如果您不允许下一个匹配项与第一个匹配项重叠,则答案可以是3,上面的算法将给出3,也可以是2。要做到这一点,只需将++POS更改为PoS+= Simult.Stand,在整个前一个匹配之后恢复搜索。

您是否尝试使用调试器来遍历代码,同时在每个执行步骤中调查变量的值?为什么要在COMP上调用子字符串?该死的,我在回答的中间,这是有效的。但是对substr的每一个调用都会创建一个临时字符串,在比较后会被销毁。这是一个巨大的记忆冲击。另一种方法见我的答案。