任务是在给定“haystack”的起始位置和结束位置的另一个字符串(haystack)中找到子字符串(needle)。开始和结束位置遵循STL约定,即结束位置是感兴趣范围之后的字符位置。
例如:使用beg_pos=0
查找“567”,“0123456789”中的end_pos=8
应返回5
,而使用beg_pos=0
和{{1}查找“567” }“0123456789”应返回end_pos=4
。
我可以想象两个简单的实现:
-1
获取子字符串位置,然后将返回值size_t pos = haystack.find(needle, beg_pos);
与pos
进行比较(如果找到)。在最坏的情况下,end_pos
函数将一直运行到字符串find
的末尾,但haystack
之后的搜索是不必要的。如果end_pos
很长,性能可能会很差。haystack
查找位置,然后返回size_t pos = haystack.substr(beg_pos, end_pos-beg_pos).find(needle);
(如果找到)。此方法避免了pos+beg_pos
之后不必要的搜索问题,但它需要分配一个新的临时字符串,这可能也存在性能问题。我想知道是否有更快的方法来完成任务。
答案 0 :(得分:1)
在C ++ 17中,我们有std::string_view
,它可以用指针和大小构造。这将允许您获取字符串的只读片段,其中不会复制任何内容。然后,您可以使用std::string_view::find
来查找该切片中是否存在子字符串。那看起来像是
std::string haystack = "lots of stuff";
std::string needle = "something";
std::string_view slice(haystack.c_str() + start, end - start); // use end - start to get size of the slice
auto pos = slice.find(needle);
if (pos == std::string::npos)
return -1;
else
return pos; // or pos + start if you need the index from the start and not just in the slice.
答案 1 :(得分:0)
前C ++ 17
这是一种我认为最快的方法。它使用std::search
,在我看来它是一个基于迭代器的substr。
在此示例中,针的位置相对于haystack的开头而不是被搜索的子字符串返回:
#include <string>
#include <iostream>
#include <algorithm>
int main()
{
using namespace std::literals;
auto my_haystack = "0123456789"s;
auto needle = "567"s;
auto find_needle = [&needle](auto first, auto last)
{
auto i = std::search(first, last, begin(needle), end(needle));
if (i == last)
return std::string::npos;
else
return std::string::size_type(std::distance(first, i));
};
auto in_substring = [](auto&& str, auto b, auto e, auto&& f) -> std::string::size_type
{
using std::begin;
auto brange = begin(str) + b;
auto erange = begin(str) + e;
auto p = f(brange, erange);
if (p != std::string::npos)
p += b;
return p;
};
auto pos = in_substring(my_haystack, 0, 4, find_needle);
std::cout << pos << std::endl;
pos = in_substring(my_haystack, 0, my_haystack.size(), find_needle);
std::cout << pos << std::endl;
pos = in_substring(my_haystack, 1, my_haystack.size(), find_needle);
std::cout << pos << std::endl;
pos = in_substring(my_haystack, 1, 4, find_needle);
std::cout << pos << std::endl;
}
示例输出(64位size_type
):
18446744073709551615
5
5
18446744073709551615