有没有比 char* 和循环更好的方法来计算字符串中的子字符串出现次数

Is there a better way to count substring occurrences within a string than char* and a loop?

本文关键字:字符串 计算 方法 char 循环 有没有 更好      更新时间:2023-10-16

我有这一行:

const char *S1 = "AaA BbB CcC DdD AaA";

我认为这会创建一个指针*S1,它位于一个常量 char 类型值,并且其中包含 AaA BbB CcC DdD AaA 值。是吗?

如果是这样,如何读取此常量值的每个字符并识别AaA发生多少次?

我正在考虑创建一个循环,将每个字母复制到不同的单元格,然后 3 个包含的 if 语句,其中第一个可以检查A,第二个可以检查a,依此类推。如果这 3 个是真的,我将像这样增加一个计数器i++.这是对的吗?

我认为这太复杂了,可以用更少的代码来完成。

你的基本方法是合理的。但是,它很复杂且无法扩展:如果您想搜索三个以上字母的单词怎么办?四个if?五if?六。。。?显然这是行不通的。

相反,请使用两个循环:一个遍历您搜索字符串("haystack"或"引用"(,另一个遍历您搜索字符串("针"或"模式"(。

但幸运的是,您甚至不必这样做,因为C++为您提供了在另一个字符串中搜索一个字符串出现的工具,即find函数:

#include <string>
#include <iostream>
int main() {
    std::string const reference = "AaA BbB CcC DdD AaA";
    std::string const pattern = "AaA";
    std::string::size_type previous = 0;
    int occurrences = 0;
    for (;;) {
        auto position = reference.find(pattern, previous);
        if (position == std::string::npos)
            break;
        previous = position + 1;
        ++occurrences;
    }
    std::cout << occurrences << " occurrences of " << pattern << 'n';
}

您可以在C++参考中查找各个类型和函数。例如,您可以在那里找到std::string::find功能,该功能为我们进行实际搜索。

请注意,这将找到嵌套模式:引用"AaAaA"将包含两次出现的"AaA"。如果这不是您想要的,请更改重新分配previous位置的行。

实现所需目标的一种简单方法是使用 strstr(str1, str2) 函数,该函数返回指向 str1 中第一次出现的 str2 的指针,如果 str2 不是 str1 的一部分,则返回一个空指针。

int count_sequence(const char *S1, const char *sequence) {
    int times, sequence_len;
    const char *ptr;
    times = 0;
    sequence_len = strlen(sequence);
    ptr = strstr(S1, sequence); //Search for the first sequence
    while(ptr != NULL) {
        times++;
        ptr = strstr(ptr + sequence_len, sequence); //search from the last position
    }
    return times;
}

C++方式:

  • 使用std::string进行字符串管理,它提供了很多好处,内存管理,迭代器,一些算法,如find
  • 如果s2 s1中不存在,则使用find std::string方法搜索s2开始的s1索引(返回虚拟值 std::string::NPOS(。

法典:

#include <iostream>
int main() {
    std::string s1("AaAaAaA");
    //std::string s1("AaA BbB CcC DdD AaA");
    std::string s2("AaA");
    int times = 0;
    size_t index = s1.find(s2, index);
    while (index != std::string::npos) {
        times++;
        index = s1.find(s2, index + 1);
    }
    std::cout << "Found '" << s2 << "' in '" << s1 << "' " 
              << times << " times" << std::endl;
}