我有std::unordered_set
个T
类型的元素和一个函数U key_of(const T& t)
。现在,我想要一个C ++结构:
std::unordered_map
的方法;至少:operator [] const,find和迭代器。使用(现代)C ++执行此操作的惯用方法(如果有的话)是什么?
备注: - 地图外观不会用于插入,删除或更改任何数据。 - 关于有序地图和有序集的答案也是相关的,尽管不那么重要。 - 性能可能缺乏,如果我想要快速的东西,我会建立地图。简单性更重要。 - 在地图立面可能认为它永远不会改变的意义上,该集合是不变的。 - 您可以假设集合中没有冗余(即没有相同密钥的元素)或建议使用多图解决方案。
答案 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>>
,Container
,AllocatorAwareContainer
,我们完全有可能完成这项工作。
注意:等式为UnorderedAssociativeContainer