【问题标题】:STL set::find redefined searchSTL set::find 重新定义的搜索
【发布时间】:2012-11-25 21:42:27
【问题描述】:

我的程序基于一组对,即

typedef std::pair<int,int> innerPair;
typedef std::pair<innerPair,int> setElement;
std::set<setElement> Foo;

innerPair 元素是真正定义 setElement 的元素,但我需要为每个元素附加一个组 ID,因此是后者 setElement 定义。

在程序的其余部分,我需要找到innerPair,而不管他们的组ID,所以我基本上需要一个函数

std::set<setElement>::iterator find(innePair);

无论其组 ID 为何,都会找到 innerPair。就目前而言,我可以简单地循环遍历所有可用的组 ID 并进行多次 find() 调用,但这远没有效率。

有没有一种简洁的方法来定义一个执行某种通配符搜索的find( ... )成员函数,还是我需要用我自己的定义重载它?

【问题讨论】:

  • 你是说innerPair是key,group ID是value?如果是这样,为什么不直接使用map
  • 看起来你真的想要std::map&lt;innerPair, int&gt;
  • 您是在寻找特定的 innerPair,还是在寻找具有给定组 ID 的所有 innerPair?
  • innerPair 是唯一定义的键,所以是的,我认为那张地图就是我要找的。​​span>

标签: c++ iterator find set std-pair


【解决方案1】:

如果您有多个元素具有相同的内部对和不同的组 ID,则可以使用 std::multimap&lt;innerPair, int&gt;

这允许您使用相同的innerPair 存储多个元素。

它还简化了使用lower_bound/upper_boundequal_range 的搜索。

【讨论】:

    【解决方案2】:

    我看到了两种可能的设计。一个可能比另一个更适用。

    innerPair 可能更适合作为具有 3 个成员(第一、第二和组 ID)的结构或 std::tuple&lt;int, int, int&gt;。组 ID 是 innerPair 对象的一部分吗?如果是这样,那么我建议这是更好的设计。

    如果不是(老实说,我认为在您的情况下不是),您应该使用 std::map&lt;innerPair,int&gt; 创建从 innerPair 对象到组 ID 的映射。然后你可以很容易地找到一个元素:

    std::map<innerPair,int> mapping;
    // Fill your map
    innerPair key = {1, 2};
    auto found_iter = mapping.find(key);
    

    您还可以通过以下方式获取特定 innerPair 的组 ID:

    int group_id = mapping[key];
    

    您不需要提供自定义比较器,因为 operator&lt; 已为 std::pair 定义。

    【讨论】:

    • 组 ID 本身不是对象的一部分。 map 容器提供了很多有趣的功能,我肯定会选择这种设计,而不是 struct 或 tuple!
    【解决方案3】:

    如果您想按部分对象进行搜索,最好不要使用std::set&lt;...&gt;,而是使用std::map&lt;...&gt;

    std::map<std::pair<int, int>, int>
    

    无论如何,这几乎具有您为std::set&lt;...&gt; 定位的值类型(不同之处在于first 成员被声明为const)。

    如果您真的坚持使用std::set&lt;...&gt;,则需要创建一个忽略最后一个second 成员的比较器类型。我不确定std::set&lt;...&gt; 是否支持混合类型比较(我认为它不支持)。

    【讨论】:

    • 只要它提供严格的弱排序,您就可以通过innerPair 对整个集合进行排序,并在所有情况下忽略组 ID。
    • 感谢您让我了解这种类型的容器!我对 C++ 的了解仍然非常有限,因为我不是 CS 学生,而是需要编写大量代码的物理学生。地图正是我所需要的。
    【解决方案4】:

    您可以使用multiset,例如带有自定义比较函数或仿函数:

    struct innerPairCompare
    {
        bool operator () (const setElement &a, const setElement &b)
        {
            const innerPair &a_ = a.first;
            const innerPair &b_ = b.first;
            return (a_.first > b_.first || a_.first = b_.first && a_.second > b_.second);
        }
    
    };
    

    然后将其用于您的multiset:

    std::multiset<setElement,innerPairCompare> Foo;
    

    它将所有具有相同innerPairsetElements 存储在同一个列表中。

    或者,如果您需要具有给定GroupID 的所有innerPair,请使用比较groupID 的函数。

    最后,如果您真的不需要将GroupIDinnerPair 放在一起,您可以使用map(或multimap),使用GroupIDinnerPair 作为Key

    【讨论】:

      【解决方案5】:

      如果您想继续使用std::set,那么您可以使用带有自定义谓词的std::find_if,看看这个answer

      基本上你会定义一个函数

      bool pairCorresponds(std::pair<int,int> element)
      

      这将为您完成工作。

      【讨论】:

      • 注意时间复杂度。
      • 这将在线性时间而不是对数时间中运行。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-22
      • 2017-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多