【问题标题】:Is there a better way to count substring occurrences within a string than char* and a loop?有没有比 char* 和循环更好的方法来计算字符串中子字符串的出现次数?
【发布时间】:2014-09-17 13:50:35
【问题描述】:

我有这行:

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

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

如果是这样,我如何读取这个常量值的每个字符并识别AaA 出现了多少次?

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

我觉得太复杂了,用更少的代码就能搞定。

【问题讨论】:

  • 如果S1 = AaAaAaA,那么你找到了多少次AaA?两三次?

标签: c++ string substring


【解决方案1】:

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

相反,使用两个循环:一个遍历您搜索 in 的字符串(“干草堆”或“引用”),一个遍历您搜索 for 的字符串(“针”或“图案”)。

但幸运的是,您甚至不必这样做,因为 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++ reference 中查找各个类型和函数。例如,您可以在那里找到the std::string::find function,它会实际搜索我们。

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

【讨论】:

    【解决方案2】:

    实现你想要的一个简单方法是使用strstr(str1, str2)函数which returns a pointer to the first occurrence of str2 in str1, or a null pointer if str2 is not part of 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++ 中使用 strstr。还有更好的方法。
    • @Demetris, #include
    • @Claudix 哦,这比strstr 更糟糕。如果你必须这样做,至少去#include &lt;cstring&gt;
    【解决方案3】:

    C++ 方式:

    • 使用std::string 进行字符串管理,它提供了很多好处,内存管理,迭代器,一些算法,如find
    • 使用std::stringfind 方法搜索s1 的索引,其中s2 开始,如果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;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-03-29
      • 1970-01-01
      • 2021-11-23
      • 2011-03-22
      • 2010-10-31
      • 2019-02-26
      • 2020-02-21
      • 2012-02-12
      相关资源
      最近更新 更多