【问题标题】:Count occurrences of a sub string in a String计算字符串中子字符串的出现次数
【发布时间】:2020-02-21 18:49:43
【问题描述】:

首先,我知道这个问题有很多重复,但我已经尝试过并且无法解决我的问题。

我有以下字符串

string s = "asdfqasdfp";

我需要遍历字符串并找出哪个子字符串出现多次。所以在这种情况下它的

asdf

我编写了以下代码,但我不知道为什么它不起作用。我从完整的字符串开始,一次向下一个。我应该得到 2 的出现值。

int t = s.length();
for (int i = 0; i < s.length(); i++) {
    string str = s.substr(0, t);
    int occurence = 0;
    size_t start = 0;
        while ((start = s.find(str, start)) != string::npos) {
            ++occurence;
            start += str.length();
        }
        if (occurence > 1) {
            cout << occurence;
        }
        else {
            --t;
        }
    }

编辑:我只想要字符串包含的最大子字符串,在这种情况下

“asdf”

【问题讨论】:

  • 对不起,如果它是幼稚的,我对 cpp 很陌生并且一直在努力。
  • 已编辑问题以阐明我想要什么
  • @rex 您显然只考虑从输入字符串开头的子字符串 (s.substr(0, t);)。这是你想要的吗?如果输入字符串是"xasdfqasdfp"怎么办?
  • @Dabiel 如果 s.substr(i, t) 不起作用,我可以将其更改为什么?
  • @Daniel 我做了 Rup 为我做的事情,它为我的问题提供了快速解决方案。但是,我现在将尝试按照您的方式进行操作,以便更好地理解。感谢您的帮助。

标签: c++ string substring


【解决方案1】:

这是您的代码的固定版本,包括 Daniel 的建议(谢谢!Daniel's demo

for (size_t t = s.length(); t >= 1; --t) {
    for (size_t i = 0; (i + t) <= s.length(); i++) {
        std::string str = s.substr(i, t);
        size_t occurence = 0;
        size_t start = 0;
        while ((start = s.find(str, start)) != std::string::npos) {
            ++occurence;
            start += str.length();
        }
        if (occurence > 1) {
            std::cout << str << " " << occurence << std::endl;
            return 0;
        }
    }
}

你需要

  1. 在 t 上循环,并在 i 循环的末尾而不是内部递减它
  2. 将 i 限制为 s.length() - t,以便始终有一个 t 长度的字符串作为 str
  3. 修复您的 substr 以从 i 而不是 0 开始

您也可以在第一次找到重复项时停止,因为这将是最大的重复项(例如,如果有两对长度为 4 的重复项,它会找到其中一个,但听起来不像您两者都需要)。您还应该始终使用 size_t 作为整数类型,因为这就是这里的字符串函数所使用的。

【讨论】:

  • 请注意: 1) 您可以以t=s.length()-1 开头(如果输入字符串非空)。 2) 当(occurence&gt;1) 为真时,您可以结束整个搜索。没有理由继续前进。 3) 为什么不简单地cout &lt;&lt; str &lt;&lt;...? 4) 将所有int 更改为size_tLive demo.
  • 糟糕,是的,我本来打算编辑掉 .c_str()。在 Visual Studio 中进行了测试,我将其保留在默认的 UTF-16 模式下,因此更容易输入。是的,我同意您的所有其他建议,但这只是一个最小的修复,而不是一个完整的修复。
【解决方案2】:

看起来不错。您需要&lt;&lt; endl; 才能在终端中查看输出吗?

【讨论】:

  • std::endl 不会让您“在终端中查看输出”。它附加一个换行序列(通常为'\n',取决于平台)并应用std::flush 以立即刷新缓冲区。
猜你喜欢
  • 2012-02-12
  • 1970-01-01
  • 2014-04-24
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多