C ++设置搜索对元素?

时间:2012-03-23 16:55:19

标签: c++ search stl std-pair stdset

所以我有一套pairs<string ,string>

我想使用find()搜索一对字符串,该字符串位于该对的“第一个”中,然后如果我首先找到该字符串,我想从该函数返回第二个字符串。

我目前的尝试是..

myList::iterator i;

i = theList.find(make_pair(realName, "*"));

return i->second;

3 个答案:

答案 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_boundupper_bound的回归是否结束。

  • 如果lower_bound返回end(),则upper_bound也会返回,并且跳过循环
  • 如果lower_bound指向it->first > key的节点,则upper_bound将指向同一节点,并跳过循环

这是范围的力量:不需要进行特殊检查,当没有匹配时范围最终为空,因此在一次检查中跳过它们的循环...