带有自定义比较器的 C++ std::find
Posted
技术标签:
【中文标题】带有自定义比较器的 C++ std::find【英文标题】:C++ std::find with a custom comparator 【发布时间】:2013-01-14 16:19:19 【问题描述】:这基本上是我想做的:
bool special_compare(const string& s1, const string& s2)
// match with wild card
std::vector<string> strings;
strings.push_back("Hello");
strings.push_back("World");
// I want this to find "Hello"
find(strings.begin(), strings.end(), "hell*", special_compare);
// And I want this to find "World"
find(strings.begin(), strings.end(), "**rld", special_compare);
但不幸的是,std::find
不能这样工作。那么只使用 STL,我怎么能做这样的事情呢?
【问题讨论】:
附注 - 比较中的字符串参数应该是const string&
而不仅仅是 string&
。顺便说一句,有趣的问题。
【参考方案1】:
根据您的 cmets,您可能正在寻找这个:
struct special_compare : public std::unary_function<std::string, bool>
explicit special_compare(const std::string &baseline) : baseline(baseline)
bool operator() (const std::string &arg)
return somehow_compare(arg, baseline);
std::string baseline;
std::find_if(strings.begin(), strings.end(), special_compare("hell*"));
【讨论】:
这正是我想要做的。【参考方案2】:你需要使用的函数是这样的:std::find_if
,因为std::find
没有比较函数。
但是std::find_if
不带值。您试图同时传递 value 和 compare ,这让我感到困惑。不管怎样,看看documentation。看看用法的区别:
auto it1 = std::find(strings.begin(), strings.end(), "hell*");
auto it2 = std::find_if(strings.begin(), strings.end(), special_compare);
希望对您有所帮助。
【讨论】:
基本上我想将strings
中的每个字符串与"hell*"
进行比较,并将其与通配符匹配。所以它会找到“你好”。希望这更有意义。
@Josh:所以认为你需要find_if
,你需要相应地实现compare函数。
我可能错了,但 compare 函数不只接受 1 个参数吗?我如何将它与我要查找的“hell*”字符串进行比较?
@Josh:您可以在函数本身内部使用"hell*"
,无需传递给它。事实上,比较函数只接受一个参数。或者你可以使用函数对象,如果你想让它通用。【参考方案3】:
您需要std::find_if()
,这很难使用,除非您使用的是 C++11 编译器。因为那时,您不需要硬编码要在某个比较器函数中搜索的值或实现仿函数对象,而是可以在 lambda 表达式中完成:
vector<string> strings;
strings.push_back("Hello");
strings.push_back("World");
find_if(strings.begin(), strings.end(), [](const string& s)
return matches_wildcard(s, "hell*");
);
然后你在某处写一个matches_wildcard()。
【讨论】:
Lambda 绝对是必经之路。没有理由为这样简单的事情创建一个完整的比较器类,尤其是在几乎每个人都拥有 C++11(+) 编译器的情况下。【参考方案4】:因为还没有人提到std::bind
,我就推荐这个
#include <functional>
bool special_compare(const std::string& s, const std::string& pattern)
// match with wild card
std::vector<std::string> strings;
auto i = find_if(strings.begin(), strings.end(), std::bind(special_compare, std::placeholders::_1, "hell*"));
【讨论】:
bind 适用于 C++11,但可以避免在 C++11 上使用 lambda,如 @nikos-c 所述。【参考方案5】:使用 C++11 lambda:
auto found = find_if(strings.begin(), strings.end(), [] (const std::string& s)
return /* you can use "hell*" here! */;
);
如果您不能使用 C++11 lambda,您可以自己创建一个函数对象。制作类型和重载运算符 ()。
【讨论】:
【参考方案6】:我想举一个具有自定义查找逻辑的自定义类的示例,但没有找到类似的答案。所以我写了这个答案,它使用自定义比较器函数 (C++11) 来查找对象。
class Student
private:
long long m_id;
// private fields
public:
long long getId() return m_id; ;
;
现在假设,我想找到m_id
与给定ID 匹配的student
对象。我可以这样写std::find_if
:
// studentList is a vector array
long long x_id = 3; // local variable
auto itr = std::find_if(studentList.begin(), studentList.end(),
[x_id](Student& std_val)
return std_val.getId() == x_id;
);
if(itr == studentList.end())
printf("nothing found");
【讨论】:
以上是关于带有自定义比较器的 C++ std::find的主要内容,如果未能解决你的问题,请参考以下文章
具有自定义比较器和 O(n) 时间的 priority_queue c++