【问题标题】:Get all the keys which matches a query in a map获取与地图中的查询匹配的所有键
【发布时间】:2012-11-02 20:50:17
【问题描述】:

假设我在地图中有多个具有相同值的键。那么在这种情况下,我如何检索与查询匹配的所有键。

或者,有没有可能告诉 find 操作在特定值之后进行搜索。
我正在使用std::map,C++。

【问题讨论】:

  • 我怀疑您可能混淆了“价值”一词。据说映射是从键映射到值,但我认为您所说的值是“键的值”,而不是“键映射到的值”。如果是这种情况,如果您重复使用相同的密钥两次,std::map 将覆盖旧条目。 std::multimap 支持同一密钥的多次使用。

标签: c++ stl map


【解决方案1】:

这样的东西对你有用吗:

void FindKeysWithValue(Value aValue, list<Key>& aList)
{
    aList.clear();

    for_each(iMap.begin(), iMap.end(), [&] (const pair<Key, Value>& aPair)
    {
        if (aPair.second == aValue)
        {
            aList.push_back(aPair.first);
        }
    });
}

【讨论】:

  • 我建议在这里使用const pair&lt;Key, Value&gt;&amp;
【解决方案2】:

关联容器可能对您没有太大帮助,因为对于std::map&lt;K, V&gt;,键恰好是唯一的,并且您选择的查询与您使用的排序关系匹配的可能性可能不会太高。如果顺序匹配,您可以使用std::map&lt;K, V&gt; 成员lower_bound()upper_bound()。对于std::multimap&lt;K, V&gt;,您也可以使用equal_range()

一般来说,即如果你的查询与订单没有真正的关系,你可以使用std::copy_if() 来获取一个匹配谓词的对象序列:

Other other;
// ...
std::vector<Other::value_type> matches;
std::copy_if(other.begin(), other.end(), 
             std::back_inserter(matches), predicate);

当复制元素的成本太高时,您可能应该考虑改用std:find_if()

for (auto it(other.begin());
    other.end() != (it = std::find_if(it, other.end(), predicate));
    ++it) {
   // do something with it
}

【讨论】:

    【解决方案3】:

    唯一的方法是遍历地图。

    此链接可能有用:Reverse map lookup

    【讨论】:

      【解决方案4】:

      如果您想要快速访问并且您不介意使用更多空间,那么您可以维护另一个映射,该映射被存储为值、键。在您的情况下,您需要处理重复的值(您将作为键存储)。

      不是一个好主意,但绝对是一个选择。

      【讨论】:

        【解决方案5】:

        map 用于高效查找键。基于值的查找效率不高,你基本上必须遍历地图,自己提取匹配项:

        for(map<A,B>::iterator i = m.begin(); i != m.end(); i++)
            if(i->second == foo)
                you_found_a_match();
        

        如果您打算经常这样做,您可以用另一种方式构建多图映射,这样您就可以有效地执行基于值的查找:

        multimap<B,A> reverse;
        for(map<A,B>::iterator i = m.begin(); i != m.end(); i++)
            reverse.insert(pair<B,A>(i->second,i->first));
        

        您现在可以轻松找到具有给定值值的键:

        matches = reverse.equal_range(value);
        for(multimap<B,A>::iterator i = matches.first; i != matches.second; i++)
            A & key = i->second;
        

        如果这些映射不会持续增长,那么简单地维护一个向量可能会更有效 > 根据该值为其定义一个比较器,然后在其上使用 equal_range。

        【讨论】:

          猜你喜欢
          • 2012-05-30
          • 2014-02-19
          • 1970-01-01
          • 2016-01-18
          • 1970-01-01
          • 2021-08-03
          • 1970-01-01
          • 1970-01-01
          • 2015-10-03
          相关资源
          最近更新 更多