所以我有一套pairs<string ,string>
我想用它find()
来搜索一个字符串,该字符串将位于该对的“第一个”中,然后如果我首先找到该字符串,我想从该函数返回第二个。
我目前的尝试是..
myList::iterator i;
i = theList.find(make_pair(realName, "*"));
return i->second;
C++11 可以接受吗?
auto it = find_if(theList.begin(), theList.end(),
[&](const pair<string, string>& val) -> bool {
return val.first == realName;
});
return it->second;
或者在 C++03 中,首先定义一个仿函数:
struct MatchFirst
{
MatchFirst(const string& realName) : realName(realName) {}
bool operator()(const pair<string, string>& val) {
return val.first == realName;
}
const string& realName;
};
然后这样称呼它:
myList::iterator it = find_if(a.begin(), a.end(), MatchFirst(realName));
return it->second;
这只会返回第一场比赛,但从你的问题来看,这就是你所期望的。
您可以std::set<std::pair<std::string, std::string> >
为此使用,但您需要一个自定义比较对象,因为该对的关系运算符为此需要两个元素。也就是说,似乎您实际上应该使用 a std::map<std::string, std::string>
。
<
for的定义std::pair
实现了字典顺序,""
是字符串的最小元素。结合这个我们得到:
typedef std::pair<std::string, std::string> StringPair;
typedef std::set<StringPair> Set;
std::string const* find_first(Set const& s, std::string const& key) {
Set::const_iterator const it = s.lower_bound(std::make_pair(key, ""));
// Check that it actually points to a valid element whose key is of interest.
if (it == s.end() or it->first != key) { return 0; }
// Yata!
return &it->second;
}
诀窍是使用lower_bound
得当。
返回指向第一个不比较小于的元素的迭代器
value
。
end()
,那么它没有发现任何有趣的东西。it->first >= key
所以我们摆脱这个>
案子(我们不感兴趣)我要指出的是,这只返回范围的第一个元素。如果您对所有元素感兴趣,请尝试:
typedef std::pair<Set::const_iterator, Set::const_iterator> SetItPair;
SetItPair equal_range_first(Set const& s, std::string const& key) {
StringPair const p = std::make_pair(key, "");
return std::make_pair(s.lower_bound(p), s.upper_bound(p));
}
s
这将返回第一个元素等于的所有节点key
。然后你只需要遍历这个范围:
for (Set::const_iterator it = range.first; it != range.second; ++it) {
// do something
}
而且您甚至不必担心返回lower_bound
或upper_bound
是否结束。
lower_bound
返回end()
,则返回,upper_bound
并跳过循环lower_bound
指向的节点it->first > key
, thenupper_bound
将指向同一个节点,并跳过循环这就是范围的力量:无需进行特殊检查,范围在没有匹配时最终为空,因此在一次检查中跳过它们的循环......