【问题标题】:C++: 'unique vector' data structureC++:“唯一向量”数据结构
【发布时间】:2019-02-11 21:03:10
【问题描述】:

我需要一个像 std::vector 或 std::list 这样的数据结构,它的元素是唯一的。大多数时候我会调用 push_back ,有时可能会擦除。当我插入一个已经存在的元素时,我需要通过一些布尔值或异常来通知我。

它应该具有的最重要的属性:插入顺序。每次我遍历它时,它都应该按照插入的顺序返回元素。

我们可以换个思路:保证元素唯一性的队列。但我不想弹出元素,而是想像处理向量或列表一样遍历它们。

什么是最适合我需要的数据结构?

【问题讨论】:

标签: c++ data-structures unique


【解决方案1】:

您可以使用std::set

当调用insert 方法时,它将返回一对pair<iterator,bool>。当元素已存在于集合中时,该对中的布尔值为 false(在这种情况下不会添加该元素)。

【讨论】:

  • 在您回答之后,我意识到我忘记了我正在寻找的最重要的财产。请再读一遍。对不起。
【解决方案2】:

使用带有常规 std::vector 和 std::set 的结构。

当你推送时,检查集合是否存在元素。当你需要迭代时,迭代向量。如果您需要从向量中擦除,也请从集合中擦除。

基本上,将集合用作备用,仅用于快速“元素的存在”检查。

// either make your class a template or use a fixed type of element
class unique_vector
{
    public:
        // implement the various operator you need like operator[]
        // alternatively, consider inheriting from std::vector
    private:
        std::set<T> m_set; // fast lookup for existence of elements
        std::vector<T> m_vector; // vector of elements
};

【讨论】:

    【解决方案3】:

    我更喜欢使用 std::unordered_set 将现有元素存储在 std::vector 中,它具有更快的 O(1) 查找时间,而 std::set 的查找时间为 O(logn)。

    【讨论】:

      【解决方案4】:

      您可以为此使用Boost.MultiIndex

      Live On Coliru

      #include <boost/multi_index_container.hpp>
      #include <boost/multi_index/sequenced_index.hpp>
      #include <boost/multi_index/hashed_index.hpp>
      #include <boost/multi_index/identity.hpp>
      
      using namespace boost::multi_index;
      
      template<typename T>
      using unique_list=multi_index_container<
       T,
       indexed_by<
         sequenced<>,
         hashed_unique<identity<T>>
       >
      >;
      
      #include <iostream>
      
      int main()
      {
        unique_list<int> l;
      
        auto print=[&](){
          const char* comma="";
          for(const auto& x:l){
            std::cout<<comma<<x;
            comma=",";
          }
          std::cout<<"\n";
        };
      
        l.push_back(0);
        l.push_back(1);
        l.push_back(2);
        l.push_back(0);
        l.push_back(2);
        l.push_back(4);
      
        print();
      }
      

      输出

      0,1,2,4
      

      【讨论】:

        猜你喜欢
        • 2012-04-26
        • 1970-01-01
        • 2016-02-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-03
        • 1970-01-01
        相关资源
        最近更新 更多