`std :: unordered_set`是一个包含一组唯一对象的关联容器。搜索,插入和删除具有平均的恒定时间复杂度。
为什么这段代码会给我编译器错误:“静态断言失败,因为......哈希不满足哈希要求”
代码粘贴如下: auto myComp = []( std::array &a, std::array &b ) { if ( a[0] == b[0] && a[1] == b[1] && a[2] == b[2] ) {...
如何将 unordered_set::contains() 与自定义类一起使用?
我第一次使用 std::unordered_set 与自定义类型,我无法弄清楚我缺少什么来为我的集合编译 contains() 。 我基本上有一个看起来像......
我第一次使用无序集与自定义类型,我无法弄清楚我缺少什么来为我的集编译包含内容。 所以我基本上有一个看起来像这样的课程......
给定任何字符,确定该字符是否属于已知字符集(而不是容器类型)的最快方法是什么。 换句话说,最快优雅的方式是什么
std::unordered_set basicWalls = FindWalls(floorPositions, cardinal2D); std::unordered_setcornerWalls = FindWalls(floorPositions, Diagonal2D); printf("基本
我正在尝试实现这个放置或合并 模板 T& EmplaceOrMerge(std::unordered_set& s, 统统、 标准::函数<
一个可能看起来微不足道的问题,但我想知道在我将包含重复整数的数组转换为 unordered_se 之后是否有一种方法可以获得唯一的整数计数...
当为unordered_set / unordered_map调用reserve(new_size)时 - 是否会导致分配新的桶数组?
AFAIU(也许我错了),unordered_set/unordered_map 使用底层数组或向量作为存储桶,每个存储桶中有一个键(或键值)列表。 所以当我们想要更多的桶、更大的数组时
我有两个 unordered_set 并想要它们的交集。我找不到库函数来做到这一点。 本质上,我想要的是这样的: 无序集 a = {1, 2, 3}; 无序集 我有两个 unordered_set 并且想要它们的交集。我找不到库函数来做到这一点。 本质上,我想要的是这样的: unordered_set<int> a = {1, 2, 3}; unordered_set<int> b = {2, 4, 1}; unordered_set<int> c = a.intersect(b); // Should be {1, 2} 我可以做类似的事情 unordered_set<int> c; for (int element : a) { if (b.count(element) > 0) { c.insert(element); } } 但是,我认为应该有一种更方便的方法来做到这一点。如果没有,有人可以解释一下为什么吗?我知道有 std::set_intersection,但这似乎只对向量起作用。 事实上,基于循环的解决方案是您可以与 std::unordered_set 一起使用的最佳选择。 有一种名为 std::set_intersection 的算法,它允许找到两个 sorted 范围的交集: 构造一个从 d_first 开始的由元素组成的排序范围 在两个排序范围 [first1, last1) 和 [first2, 最后2). 当您处理 std::unordered_set 时,您无法应用此算法,因为std::unordered_set中的元素没有保证顺序。 我的建议是坚持使用循环,因为它明确说明了您想要实现的目标,并且具有线性复杂度(O(N),其中 N 是您使用 for 循环遍历的无序集合中的元素数量)这是您可能实现的最佳复杂性。 正如已接受的答案所解释的那样,直接不能做你想要的事情,并且std::set_intersection不适合交叉std::unordered_set,尽管听起来像这样。理想的解决方案取决于您使用的 C++ 标准。 给定两套std::unordered_set<T> a, b; ... 就地 ...将a转入路口a & b的最佳方法如下: // C++20 (needs <unordered_set>) std::erase_if(a, [&b](int e) { return !b.contains(e); }); // C++11 (needs <unordered_set>) for (auto it = a.begin(); it != a.end();) { if (!b.count(*it)) it = a.erase(it); else ++it; } 不可修改 或者,计算一个新集合 c,其中包含 a 和 b 的交集: // C++23 (needs <unordered_set>, <ranges>) std::unordered_set<int> c(std::from_range, a | std::views::filter([&b](int e) { return b.contains(e); }); // C++20 (needs <unordered_set>, <ranges>) auto view = a | std::views::filter([&b](int e) { return b.contains(e); }; std::unordered_set<int> c(view.begin(), view.end()); // C++11 (needs <unordered_set>) std::unordered_set<int> c; // TODO: consider reserving a size (optimistically |a| + |b|) for (int e : a) { if (b.count(e)) { c.insert(e); } } std 有一个函数称为 set_intersection。但是,使用 std::set 作为输入参数会具有非常高的复杂性。更好的解决方案是,从这些集合中创建两个向量,并使用 set_intersection 和向量作为输入参数。
自定义类的嵌套 unordered_set 的自定义哈希和等价函数
我有一个 struct MyStruct,它有一个 unordered_set,它有自己的哈希函数 MyStructHash,以便我可以定义 unordered_set struct_set;。 我的结构是
C++ STL:std::unordered set 和 std::unordered_map 哈希如何工作?
我试图了解STL无序集/映射(即哈希映射)如何工作。 我知道初始哈希表大小(即桶数)设置为 8,当更多元素添加到集合中时......
我知道人们在不关心集合中元素的顺序时使用unordered_set。但是,当我在 C++ Shell 上运行示例程序时 #包括 #包括<
std::unordered_set 与 constexpr std::vector 用于存储不可变数据
不幸的是,即使 C++23 也没有 constexpr 集:( 我希望存储适量(可能~100)的字符串,代表系统中存在的不同配置。我只需要
我正在尝试创建一个包含指向同一类的 std::unordered_set 指针的类,但我无法找到在声明该类之前准备哈希函数的方法。 结构散列 {...
为了找出适合我特定目的的最佳容器类型,我比较了 std::vector、排序 std::vector 与二分搜索、std::set 和 std::unordered_set 的查找时间。这是...
我需要一些描述不可变的有序集的类/接口名称(按输入顺序,如 LinkedHashSet)。我当然可以像这样使用该类: 类 Foo { 公开最终集 我需要一些类/接口名称来描述不可变的有序集(按输入顺序,如LinkedHashSet)。我当然可以像这样使用这个类: class Foo { public final Set<Long> frozenOrderedSet; public Foo(List<Long> input) { frozenOrderedSet = Collections.unmodifiableSet(new LinkedHashSet(input)); } } 但这并不能澄清我的方法。我想向阅读源代码的每个人明确表示,该集合是不可修改且唯一的,同时使用 for(Long l : set){} 保持其顺序。 Guava 的 ImmutableSet 提供 a high-performance, immutable Set with reliable, user-specified iteration order. 还有像 ImmutableSortedSet 这样的变体。 最简单的方法是扩展 Set 来创建自定义的不可变 Set。 public CustomImmutableSet(){ return Collections.unmodifyingSet(new LinkedHashSet(输入)); } 这样,每个阅读源代码的人都会清楚该集合是不可修改且唯一的 Bozho 有问题Java 不可变集合: 不可修改的集合通常是只读视图(包装器) 其他收藏。您无法添加、删除或清除它们,但 底层集合可能会改变。 不可变集合根本无法更改 - 它们不会换行 另一个系列 - 他们有自己的元素。 这是番石榴的 ImmutableList 的引用 与 Collections.unmodifyingList(java.util.List) 不同, 这是一个仍然可以改变的单独集合的视图, ImmutableList 的实例包含它自己的私有数据,并且永远不会 改变。 所以,基本上,为了从 可变集合,您必须将其元素复制到新集合中,并且 禁止所有操作。 所以基本上你可以创建类 TreeSet 的子类并覆盖所有 :add、remove 等方法,以抛出一个异常,说明这是不可变的集合。此外,您还必须在此类中使用一个参数创建复制构造函数TreeSet setToCopyFrom。 java.util.Collection源内部实现了使用静态包范围内部类生成不可修改集合的方法。 您可以将这些类的实现从 JDK 中的源代码复制到您的包中并将其公开。然后,您可以在代码中使用类型说明符,明确声明集合不可修改、已排序等。 毫无疑问,JDK 开发人员选择不公开这些类型是有原因的,但我不知道它是什么。 从 JDK 修改代码 此代码来自 JDK 21,实现与 JDK 相同,但类被定义为公共的,因此可以从任何包中使用它们。 不可修改的集合.java package org.example.unmodifable; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; import java.util.Spliterator; import java.util.function.Consumer; import java.util.function.IntFunction; import java.util.function.Predicate; import java.util.stream.Stream; class UnmodifiableCollection<E> implements Collection<E>, Serializable { @java.io.Serial private static final long serialVersionUID = 1820017752578914078L; @SuppressWarnings("serial") // Conditionally serializable final Collection<? extends E> c; UnmodifiableCollection(Collection<? extends E> c) { if (c == null) throw new NullPointerException(); this.c = c; } public int size() { return c.size(); } public boolean isEmpty() { return c.isEmpty(); } public boolean contains(Object o) { return c.contains(o); } public Object[] toArray() { return c.toArray(); } public <T> T[] toArray(T[] a) { return c.toArray(a); } public <T> T[] toArray(IntFunction<T[]> f) { return c.toArray(f); } public String toString() { return c.toString(); } public Iterator<E> iterator() { return new Iterator<>() { private final Iterator<? extends E> i = c.iterator(); public boolean hasNext() { return i.hasNext(); } public E next() { return i.next(); } public void remove() { throw new UnsupportedOperationException(); } @Override public void forEachRemaining(Consumer<? super E> action) { // Use backing collection version i.forEachRemaining(action); } }; } public boolean add(E e) { throw new UnsupportedOperationException(); } public boolean remove(Object o) { throw new UnsupportedOperationException(); } public boolean containsAll(Collection<?> coll) { return c.containsAll(coll); } public boolean addAll(Collection<? extends E> coll) { throw new UnsupportedOperationException(); } public boolean removeAll(Collection<?> coll) { throw new UnsupportedOperationException(); } public boolean retainAll(Collection<?> coll) { throw new UnsupportedOperationException(); } public void clear() { throw new UnsupportedOperationException(); } // Override default methods in Collection @Override public void forEach(Consumer<? super E> action) { c.forEach(action); } @Override public boolean removeIf(Predicate<? super E> filter) { throw new UnsupportedOperationException(); } @SuppressWarnings("unchecked") @Override public Spliterator<E> spliterator() { return (Spliterator<E>) c.spliterator(); } @SuppressWarnings("unchecked") @Override public Stream<E> stream() { return (Stream<E>) c.stream(); } @SuppressWarnings("unchecked") @Override public Stream<E> parallelStream() { return (Stream<E>) c.parallelStream(); } } UnmodifyingSet.java package org.example.unmodifable; import java.io.Serializable; import java.util.Set; class UnmodifiableSet<E> extends UnmodifiableCollection<E> implements Set<E>, Serializable { @java.io.Serial private static final long serialVersionUID = -9215047833775013803L; UnmodifiableSet(Set<? extends E> s) { super(s); } public boolean equals(Object o) { return o == this || c.equals(o); } public int hashCode() { return c.hashCode(); } } 不可修改的SortedSet.java package org.example.unmodifable; import java.io.Serializable; import java.util.Comparator; import java.util.SortedSet; public class UnmodifiableSortedSet<E> extends UnmodifiableSet<E> implements SortedSet<E>, Serializable { @java.io.Serial private static final long serialVersionUID = -4929149591599911165L; @SuppressWarnings("serial") // Conditionally serializable private final SortedSet<E> ss; UnmodifiableSortedSet(SortedSet<E> s) {super(s); ss = s;} public Comparator<? super E> comparator() {return ss.comparator();} public SortedSet<E> subSet(E fromElement, E toElement) { return new UnmodifiableSortedSet<>(ss.subSet(fromElement,toElement)); } public SortedSet<E> headSet(E toElement) { return new UnmodifiableSortedSet<>(ss.headSet(toElement)); } public SortedSet<E> tailSet(E fromElement) { return new UnmodifiableSortedSet<>(ss.tailSet(fromElement)); } public E first() {return ss.first();} public E last() {return ss.last();} } 测试用例 不可修改的SortedSetTest.java package org.example.unmodifable; import java.util.List; import java.util.TreeSet; public class UnmodifiableSortedSetTest { public static void main(String[] args) { UnmodifiableSortedSet<String> frozenAnimals = new UnmodifiableSortedSet<>( new TreeSet<>(List.of("dog", "cat", "lion", "cat")) ); System.out.println(frozenAnimals); try { frozenAnimals.add("pigeon"); } catch (UnsupportedOperationException e) { System.out.println("You can't modify the frozen list of animals."); } } } 测试输出: [cat, dog, lion] You can't modify the frozen list of animals.
将 EdgeList 作为 unordered_set 存储在 Boost Graph Library 上
我正在重现一个科学实验,我需要将图的边集存储为无序集。我正在尝试使用 BGL adjacency_graph,我认为最后一个参数是 hash_...
在shared_ptr的unordered_set中查找一个值
我想在unordered_set中找到一个值,但失败了: typedef std::shared_ptr IntPtr; std::unordered_set s; s.insert(std::make_shared(42)); 布尔找到 = s.fi...
为什么std::set没有提供try_emplace成员函数?
std::map(和std::unordered_map)的try_emplace成员函数的一个优点是,如果映射中已存在键,则它不会分配新节点。我想知道为什么这个成员函数有...
我试图在 std::unordered_set 的上下文中理解哈希。 Cppreference 给出了这样的解释: 在内部,元素不按任何特定顺序排序,但是 组织成降压...