std :: unordered_set的std :: unordered_map外观 - 如何?

时间:2015-12-09 09:57:05

标签: c++ c++11 idioms idiomatic unordered-set

我有std::unordered_setT类型的元素和一个函数U key_of(const T& t)。现在,我想要一个C ++结构:

  • 支持一些std::unordered_map的方法;至少:operator [] const,find和迭代器。
  • 不会产生实际构建地图的存储(甚至不包括T * s)
  • 由集合支持,即集合中每个元素e都有一个映射条目,有一个映射条目(key_of(e),e)。

使用(现代)C ++执行此操作的惯用方法(如果有的话)是什么?

备注: - 地图外观不会用于插入,删除或更改任何数据。 - 关于有序地图和有序集的答案也是相关的,尽管不那么重要。 - 性能可能缺乏,如果我想要快速的东西,我会建立地图。简单性更重要。 - 在地图立面可能认为它永远不会改变的意义上,该集合是不变的。 - 您可以假设集合中没有冗余(即没有相同密钥的元素)或建议使用多图解决方案。

2 个答案:

答案 0 :(得分:0)

我觉得非常短视,但是使用无序集的迭代器的问题在哪里,使用std::find模仿地图查找,并且找到operator[]的实现是微不足道的。当然表现并不好,但是如果不愿意甚至存储额外的指针,我看不出你如何能够获得更好的性能。

或者使用地图,并修改插入以检查重复的条目,这些条目应该是微不足道的,因为密钥是key_of(value)并阻止它。

伪代码(lambda的C ++ 14,可以通过辅助函数轻松解决):

template<typename S, typename K> //set contained type, key type
class mapView { 
        typedef std::unordered_set<S> set_t;
        set_t& set;
    public:
        mapView(const set_t& set) : set(set) {}
        set_t::iterator find(const K& key) {
            return std::find(set.begin(), set.end(), [&](element){return key_of(element)==key;});
        }
        S& operator[](U&& key) {
            return *find(key);
        }
        //const declarations of above
        //forward begin/end etc. to return sets iterators i.e.
        set::iterator begin() {
            return set.begin();
        }
};

答案 1 :(得分:0)

给定@Override public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); orderListView = (ListView) view.findViewById(R.id.listViewOrder); orderListView.setAdapter(adapter); } 的概念,我们构建std::unordered_set<T>std::unordered_map<K, V>K = key_of(const T& t)V = T施加了巨大的约束。

  • key_of 双射。注入性,即key_of是满足地图的关键唯一性所必需的。 主观性也可能是必需的,否则您的地图不能包含不使用key_of计算的元素z。您没有指定将如何构造该结构,因此请将其删除。
  • for any x, y E T : key_of(x) == key_of(y) -> x == y应保留key_of的碰撞概率。这不是一个大问题,因为如果是双射的,你可以建立Hash_v(T x),使碰撞的概率完全相同。

满足这些条件后,与使用Hash_u(U k)构建std::unordered_map<K, V>没有什么不同。鉴于both requires std::unordered_set<std::pair<K, V>>ContainerAllocatorAwareContainer,我们完全有可能完成这项工作。

注意:等式为UnorderedAssociativeContainer