我试图想出一个lambda,它允许std :: equal_range返回一个搜索字符串作为前缀的范围。因为这可能没有措辞,例如:
给出字符串向量:
我希望迭代器返回
我如何为完成此操作的std :: equal_range编写比较lambda,或者std :: equal_range不是作业的工具?
答案 0 :(得分:2)
我认为你只需要让比较器只比较前缀的长度和这样的元素:
std::vector<std::string> v
{
"C:/users/andy/documents/screenshot.jpg",
"C:/users/bob/desktop/file.txt",
"C:/users/bob/desktop/picture.png",
"C:/users/bob/desktop/video.mp4",
"C:/users/john/desktop/note.txt",
};
std::sort(std::begin(v), std::end(v));
std::string const prefix = "C:/users/bob/desktop/";
auto lb = std::lower_bound(std::begin(v), std::end(v), prefix);
// For the upper bound we want to view the vector's data as if
// every element was truncated to the size of the prefix.
// Then perform a normal match.
auto ub = std::upper_bound(lb, std::end(v), prefix,
[&](std::string const& s1, std::string const& s2)
{
// compare UP TO the length of the prefix and no farther
if(auto cmp = std::strncmp(s1.data(), s2.data(), prefix.size()))
return cmp < 0;
// The strings are equal to the length of the prefix so
// behave as if they are equal. That means s1 < s2 == false
return false;
});
// make the answer look like we used std::equal_range
// (if that's what's needed)
auto range = std::make_pair(lb, ub);
for(auto itr = range.first; itr != range.second; ++itr)
std::cout << *itr << '\n';
<强>输出:强>
C:/users/bob/desktop/file.txt
C:/users/bob/desktop/picture.png
C:/users/bob/desktop/video.mp4
解释为什么这个工作想象采取矢量并对其进行排序。然后想象一下访问每个元素并将它们截断为前缀的长度。你将留下一个排序的向量,没有比前缀更长的元素。此时,简单的std::equal_range
可以满足您的需求。因此,我们需要做的就是构造一个行为 的比较器,好像 容器元素已被截断为前缀的长度并在我们的{{1}中使用该比较器搜索(或双std::equal_range
搜索)。