【问题标题】:C++ How to calculate the number time a string occurs in a dataC ++如何计算字符串在数据中出现的次数
【发布时间】:2011-05-20 04:26:24
【问题描述】:

我想测量以下两件事:

  • 一个逗号出现多少次 std::std,例如如果str ="1,2,3,4,1,2," 然后str.Count(',') 在上述情况下返回我6 字符串
  • 第二件事也类似 第一个但不是单一的 char 我想计算数字 字符串的出现次数,例如 str.FindAllOccurancesOF("1,2,") 回复我2

c++ 中是否有任何内置函数来计算这个或者我需要为此编写自定义代码?

【问题讨论】:

  • 第二个有几种解决方案,您必须确定实际发生的情况。 str="AAAAAAAAAA"; str.FindAllOccurancesOf("AAA"); 的结果是什么?
  • @Bo Persson Nice Catch 但是在我们的例子中,模式必须包含两个或多个元素,例如“1,2”形成一个模式,因为它包含至少两个元素(即 1 和 2),但“1”不形成一个模式,因为它只包含一个元素
  • 我认为@Bo 的意思是,您必须为在"AAAAAAAA" 中计算"AA" 的出现次数的情况定义所需的行为。答案应该是 4(无重叠)还是 7(有重叠)?

标签: c++ stdstring


【解决方案1】:

关于第一个 -

std::string str="1,2,3,4,1,2," ;
std::count( str.begin(), str.end(), ',' ) ; // include algorithm header

编辑:

使用string::find -

#include <string>
#include <iostream>

using namespace std;

int main()
{
        string str1 = "1,2,3,1,2,1,2,2,1,2," ;
        string str2 = "1,2," ;

        int count = 0 ;
        int pos = -4;

        while( (pos = str1.find(str2, pos+4) ) != -1 ) // +4 because for the next 
                                                       // iteration current found
                                                       // sequence should be eliminated
        {
            ++count ;         
        }
        cout << count ;
}

IdeOne results

【讨论】:

  • 你为什么要擦除?为什么不从当前位置 +1 进行查找 - 你的方式效率非常低。
  • @Rikardo - 感谢您提高我的效率 :)
  • 你不能通过模式的大小来转发位置,你必须构建一个前缀表 kmp 样式或者只是从下一个位置开始查找,也就是从当前位置开始 +1。跨度>
【解决方案2】:

使用 std::string::find 方法之一,您可以单步执行引用字符串,每次找到子字符串时计数。无需复制或擦除。另外,使用std::string::npos 来检查是否找到了模式,而不是文字-1。此外,使用子字符串的大小std::string::size(),可以避免对步长进行硬编码(其他答案中的文字4

size_t stringCount(const std::string& referenceString,
                   const std::string& subString) {

  const size_t step = subString.size();

  size_t count(0);
  size_t pos(0) ;

  while( (pos=referenceString.find(subString, pos)) !=std::string::npos) {
    pos +=step;
    ++count ;
  }

  return count;

}

EDIT:此函数不允许重叠,即在字符串"AAAAAAAA" 中搜索子字符串"AA" 的结果为4。为了允许重叠,这条线

pos += step

应该替换为

++pos

这将产生7 的计数。问题中未正确指定所需的行为,因此我选择了一种可能性。

【讨论】:

  • 你不能按照模式的大小前进,想想“aaaa”或“abcabc”等形式的模式 - 不知道为什么这个解决方案被选为正确的。
  • @Rikardo,它通过了我的测试,但也许我错过了一些东西。你能给我一个它不起作用的字符串和子字符串的例子吗?
  • 我对 CPP 还很陌生,有人能解释一下为什么 pos = referenceString.find(subString, pos)) 吗?这是代码中唯一让我感到困惑的部分。
【解决方案3】:

如果您使用的是char*(C 风格)字符串,则可以尝试以下操作(伪代码): 对于发生的字符计数:

const char *str ="1,2,3,4,1,2,", *p = str - 1;
int count = 0
while(0 != (p = strchr(++p, ',')))
  count ++;

用于计数字符串发生:

const char *str ="1,2,3,4,1,2,", *p = str - 1;
int count = 0;
while(0 != (p = strstr(++p, "1,2,")))
  count ++;

【讨论】:

    【解决方案4】:

    string::find() 会带你上路。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-02-04
      • 2011-04-21
      • 2021-12-29
      • 2012-10-03
      • 1970-01-01
      • 2010-09-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多