C++设置对配对元素的搜索?

发布于 2025-01-24 19:35:40 字数 277 浏览 4 评论 0原文

因此,我有一组pairs< string,string>

,并且我想使用find()搜索一个字符串,该字符串将在该字符串中配对,然后,如果我第一次找到该字符串,我想从该功能返回第二个字符串。

我目前的尝试是..

myList::iterator i;

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

return i->second;

So I have a set of pairs<string ,string>

And I want to use find() to search for a single string which would be in the "first" of the pair, then if I find that string in first I want to return second from that function.

My current attempt is..

myList::iterator i;

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

return i->second;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

待"谢繁草 2025-01-31 19:35:40

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;
};

然后将其称为So:

myList::iterator it = find_if(a.begin(), a.end(), MatchFirst(realName));
return it->second;

这只会返回第一场比赛,但是从您的问题来看,看起来这就是您所期望的。

Is C++11 acceptable?

auto it = find_if(theList.begin(), theList.end(),
    [&](const pair<string, string>& val) -> bool {
        return val.first == realName;
    });

return it->second;

Or in C++03, first define a functor:

struct MatchFirst
{
        MatchFirst(const string& realName) : realName(realName) {}

        bool operator()(const pair<string, string>& val) {
                return val.first == realName;
        }

        const string& realName;
};

then call it like so:

myList::iterator it = find_if(a.begin(), a.end(), MatchFirst(realName));
return it->second;

This will only return the first match, but from your question, it looks like that's all you're expecting.

↙厌世 2025-01-31 19:35:40

您可以使用std :: set&lt; std :: pair&lt; std :: string,std :: string&gt; &gt;为此,您将需要自定义
对此进行比较对象,因为这对夫妇的关系操作员为此采取了这两个元素。也就是说,似乎您实际上应该使用std :: map&lt; std :: String,std :: string&gt;而不是。

You can use std::set<std::pair<std::string, std::string> > for this but you will need a custom
comparison object for this because the pair's relational operator takes both elements for this. That said, it seems as if you actually should use a std::map<std::string, std::string> instead.

别想她 2025-01-31 19:35:40

&lt;的定义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-&gt; first&gt; = key,因此我们摆脱了&gt;案例(我们对我们不感兴趣),

我会指出,尽管这只是返回该范围的第一个元素。如果您对所有元素感兴趣,请尝试:

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-&gt; first&gt;的节点键,然后upper_bound将指向相同的节点,而跳过了

范围的循环:无需进行特殊检查,范围最终是空的。没有匹配,因此在它们上面的循环...一张支票跳过。

The definition of < for std::pair implements a lexicographical order and "" is the minimum element for strings. Combining this we get:

 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;
 }

The trick is using lower_bound appropriately.

Returns an iterator pointing to the first element which does not compare less than value.

  • If it returns end(), then it did not find anything interesting.
  • Otherwise, it->first >= key so we get rid of the > case (of no interest to us)

I would point out though that this only returns the first element of the range. If you are interested in all elements, try:

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));
}

This will return the full range of nodes in s whose first element is equal to key. You then just have to iterate over this range:

for (Set::const_iterator it = range.first; it != range.second; ++it) {
  // do something
}

And you don't even have to worry whether the return of lower_bound or upper_bound was end or not.

  • if lower_bound returns end(), then so does upper_bound, and the loop is skipped
  • if lower_bound points to a node for which it->first > key, then upper_bound will point to that same node, and the loop is skipped

That is the power of ranges: no need to make special checks, the ranges just end up empty when there is no match, and so the loop over them... is skipped in a single check.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文