【发布时间】:2013-06-10 11:55:20
【问题描述】:
我查看了网站,但没有直接回答以下问题。
在 C++ 中查找字符串中第 n 次出现的子字符串的最有效方法是什么?
此处的示例显示了如何找到第二个匹配项: http://www.cplusplus.com/reference/string/string/find/
但是首先找到第一个匹配项,然后使用该位置搜索下一个匹配项等以找到第 n 个匹配项,似乎效率很低。如果你想要第25场比赛的位置,有没有更快的方法?
编辑:在更大的上下文中,我正在逐行读取文件,对项目的每个响应都有一个分数,有些则丢失了,得到一个NA 字符串。所有项目都用空格分隔。
我希望有排除某些项目的选项,因此仅从项目 35 到 80、90 到 120 和 150-200 进行搜索。 所以我现在做的是这样的:
string blockedLine(string line)
{
int b_start[] = {35, 90, 150};
int b_end[] = {80, 120, 200};
std::vector<int> space_matches = KMP(line, " ");
string cuttedLine = "";
for (int i = 0; i < 3; i++)
{
cuttedLine.append(line.substr(space_matches[b_start[i]],
space_matches[b_end[i]]));
}
return(cuttedLine);
}
KMP 是其中一个 cmets 中提到的函数,它可以获取空间出现的位置,并将它们存储在 space_matches 中。
然后我计算NA 在这个附加字符串中的出现次数。
问题是,如果没有这个附加,在大约 200k 行上读取整行只需要 1 秒。当我使用这种附加方法获取子字符串时,需要 14 秒,这太慢了。
有哪些改进可以加快速度?
【问题讨论】:
-
我会用谷歌搜索 C++ String Tokenizer,它应该会生成一个列表或一个向量。
-
@ForEveR
rfind不是要找到最后一次出现吗? -
有一些巧妙的技巧可用于非常大的数据集,但对于大多数较小的数据集,您最好只在任一端循环。 (显然还取决于您所说的最快是什么意思,以及您是多次搜索还是只搜索一次)
-
我第二个 @MatsPetersson - 听起来很像 KMP 的工作 (en.wikibooks.org/wiki/Algorithm_Implementation/String_searching/…)