使用rfind查找所有事件,流程挑战?

时间:2014-05-30 16:44:53

标签: c++ string workflow

根据c ++教程和关于find()的教学,实现了以下代码,以便在string中搜索所有“cat”事件:

std::string input;
std::size_t i = 0, x_appearances = 0;
std::getline(std::cin,input);   
for(i = input.find("cat",0); i != std::string::npos; i=input.find("cat", i))
{
    ++x_appearances;
    ++i; //Move past the last discovered instance to avoid finding the same string
}

然后教程挑战学徒改变find() rfind(),这就是问题出现的地方,首先我尝试了一些看似明显的方法:

for(i = input.rfind("cat",input.length()); i != std::string::npos; i=input.rfind("cat", i))
{
    ++x_appearances;
    --i; //Move past the last discovered instance to avoid finding the same string
}

但是通过这个解决方案我陷入了无限循环。然后我发现它发生了,因为增量是在条件检查之前执行的,并且增量rfind()总是找到匹配,即使是i==std::string::npos(如果匹配在字符串的开头,例如“猫”)。我的最终解决方案是:

int n=input.length();
for(i = input.rfind("cat",input.length()); n>0 && i!=std::string::npos; i=input.rfind("cat", i))
{
    ++x_appearances;
    n=i;
    --i; //Move past the last discovered instance to avoid finding the same string
}

使用n我可以跟踪string中的位置,并在搜索完整个for loop后退出string

所以我的问题是:我的方法是否正确?我需要一个额外的变量还是有其他更简单的方法吗?

1 个答案:

答案 0 :(得分:1)

for(i = input.rfind("cat",input.length()); i != std::string::npos; i=input.rfind("cat", i))
{
    ++x_appearances;
    --i; //Move past the last discovered instance to avoid finding the same string
}

以上问题是循环内的--i。假设输入字符串以“cat”开头。您的算法最终会找到i为0的“cat”。由于您已将i声明为std::size_t,因此从0减去1会产生最大的std::size_t 。没有警告,没有溢出,没有未定义的行为。根据标准,这正是无符号整数的工作方式。

不知何故,你需要处理这种特殊情况。您可以在循环中使用辅助变量和更复杂的测试。另一种方法是保持代码简单,同时明显地明确处理这种特殊情况:

for (i = input.rfind("cat"); i != std::string::npos; i=input.rfind("cat", i-1))
{
    ++x_appearances;
    // Finding "cat" at the start means we're done.
    if (i == 0) {
       break;
    }
}

另请注意,我已经改变了循环语句。 pos的默认值为std::string::npos,表示从字符串末尾搜索。初始化器不需要第二个参数。我还将--i移到了for循环的更新部分,将input.rfind("cat",i)更改为input.rfind("cat",i-1)。由于此时i总是正数,因此减去一个没有危险。