所以我有一套pairs<string ,string>
我想使用find()
搜索一对字符串,该字符串位于该对的“第一个”中,然后如果我首先找到该字符串,我想从该函数返回第二个字符串。
我目前的尝试是..
myList::iterator i;
i = theList.find(make_pair(realName, "*"));
return i->second;
答案 0 :(得分:6)
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;
这只会返回第一场比赛,但是根据你的问题,看起来就像你所期待的那样。
答案 1 :(得分:2)
您可以使用std::set<std::pair<std::string, std::string> >
,但您需要自定义
比较对象,因为该对的关系运算符为此获取两个元素。也就是说,似乎你实际上应该使用std::map<std::string, std::string>
代替。
答案 2 :(得分:1)
<
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
的节点,则upper_bound
将指向同一节点,并跳过循环这是范围的力量:不需要进行特殊检查,当没有匹配时范围最终为空,因此在一次检查中跳过它们的循环...