std::unordered_set 迭代器遍历的复杂性

2024-04-25

我最近玩了一个std::unordered_set http://en.cppreference.com/w/cpp/container/unordered_set。我怀疑我的 STL 版本会跟踪某些 FILO 数据结构(看起来像列表)中的非空存储桶。我想这样做是为了提供O(n)完整的时间穿越std::unordered_set (where n表示 a 中的元素数量unordered_set with m水桶和m远大于n)。这改进了对所有存储桶的简单遍历O(m) time.

我已经测试过,确实可以遍历大量且非常稀疏的数据unordered_sets (with begin - end)比简单地遍历所有桶要快得多。

Question:这个遍历运行时间有标准保证吗?或者这只是我特定标准库的一个功能?


这是我可以使用的测试代码:

#include <iostream>
#include <vector>
#include <numeric>
#include <unordered_set>
using namespace std;

void test(vector<int> data, int alloc_size) {
   unordered_set<int> set(alloc_size);
   for (auto i: data) {
      set.insert(i);
   }

   for (size_t bidx = 0; bidx < set.bucket_count(); ++bidx) {
      cout << "[B" << bidx << ":";
      for (auto bit = set.begin(bidx); bit != set.end(bidx); ++bit) {
         cout << " " << *bit;
      }
      cout << "] ";
   }

   cout << "  {";
   for (auto const & d: set) {
      cout << d << " ";
   }
   cout << "}" << endl;
}

int main() {
   test({1, 2, 0}, 3);
   test({1, 2, 0, 7}, 3);
   test({18, 6, 11, 3, 13, 4}, 20);
   test({18, 6, 11, 3, 13, 4, 34}, 20);
}

哪个打印:

[B0: 0] [B1: 1] [B2: 2] [B3:] [B4:]   {0 2 1 }
[B0: 0] [B1: 1] [B2: 7 2] [B3:] [B4:]   {0 7 2 1 }
[B0:] [B1:] [B2:] [B3: 3] [B4: 4] [B5:] [B6: 6] [B7:] [B8:] [B9:] [B10:] [B11: 11] [B12:] [B13: 13] [B14:] [B15:] [B16:] [B17:] [B18: 18] [B19:] [B20:] [B21:] [B22:]   {4 13 3 11 6 18 }
[B0:] [B1:] [B2:] [B3: 3] [B4: 4] [B5:] [B6: 6] [B7:] [B8:] [B9:] [B10:] [B11: 34 11] [B12:] [B13: 13] [B14:] [B15:] [B16:] [B17:] [B18: 18] [B19:] [B20:] [B21:] [B22:]   {4 13 3 34 11 6 18 }

看来begin - end遍历以桶变为非空的相反顺序报告桶(参见第一行和第三行)。插入已经非空的桶中不会改变这个顺序(参见第二行和第四行)。


简而言之:是的,这是由标准保证的。

解释

所有迭代器都必须有一个O(n)遍历时间复杂度(其中n是遍历的项目数量)。这是因为迭代器上的每个操作都具有恒定的时间复杂度(O(1)),包括将迭代器前进一位。

根据标准(第 24.2.1 §8 节):

所有类别的迭代器仅需要那些可在恒定时间(摊销)内为给定类别实现的函数。因此,迭代器的需求表没有复杂性列。

因此,当迭代 a 的项目时std::unordered_set,时间复杂度为O(n) (with n集合中的项目数量)。

不相信?

从字面上看上面的引用只能保证恒定时间操作可实现的。这并不能阻止特定实现的时间复杂度比实际实现更差可实现的。这可能是由于用词不当造成的,希望没有认真的实现真正做到这一点。

标准中唯一可以帮助解决这种歧义的地方是第 24.4.4 §1 节,其中标准对此进行了说明std::advance http://en.cppreference.com/w/cpp/iterator/advance and std::distance http://en.cppreference.com/w/cpp/iterator/distance :

这些函数模板使用+ and -对于随机访问迭代器(因此,它们的时间是恒定的);对于输入、前向和双向迭代器,他们使用++提供线性时间 实施。

So, the ++对前向迭代器的操作(如用于std::unordered_set http://en.cppreference.com/w/cpp/container/unordered_set) 隐含为常数时间操作。

总之,虽然第一句话的措辞含糊不清,但第二句话证实了意图。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::unordered_set 迭代器遍历的复杂性 的相关文章

随机推荐

  • 将多个工作表导入到 R 中的多个数据框中

    我有一个包含很多工作表的 Excel 文件 我需要一个代码来将每个工作表导入到单独的数据框中 该数据框架的命名方式与 Excel 中的工作表名称相同 例如 选项卡 A B C 将分别作为数据框 A B 和 C 导入 从其他线程中 我看到了这
  • 无法从“int *”转换为“int []”?

    我知道这可能是一个常见问题 但我尝试搜索但仍然找不到明确的答案 我有以下代码 int f int a 1 2 3 return a int main int a f Error here getch return 0 此代码产生错误消息 C
  • 无法在后台任务中调用 Task.Run()

    我想在后台任务的线程中做一些事情 所以我尝试使用 Task Run 但它不起作用 任何人都可以向我展示另一种在后台任务中创建线程的方法 这是我的代码 public sealed class KatzBackgroundTask IBackg
  • 无法将属性与数字进行比较。错误:“‘AnsibleUnsafeText’和‘int’实例之间不支持”

    getent database passwd debug var getent passwd dict2items selectattr value 1 gt 1000 map attribute key list 输出是 TASK deb
  • Fortran 03/08(gfortran 编译器)中使用无限多态类型进行数组操作

    我想通过以下方式实现有用的数组操作 添加元素 删除元素 通过可分配 指针 二叉树结构实现不同的实现 class 特征 无限多态性 我使用 gfortran 5 0 应该可以处理这样的功能 我需要它 以免为我使用的每种类型重复相同的代码 这应
  • 如何在 Django 中创建 unique_for_field slug?

    姜戈有一个日期唯一 http docs djangoproject com en dev ref models fields unique for date您可以在将 SlugField 添加到模型时设置的属性 这会导致 slug 仅对于您
  • 像在eclipse中一样关闭intellij idea中未使用的模块

    据我所知 目前 intellij idea 中没有任何功能可以做到这一点 我不知道为什么 但他们不支持这样做 至少这是我通过所有研究发现的结果 也许我们中的一些人用不同的方式来解决这个问题 如何在 intellij 中使用多个模块 在处理多
  • 如何从 USB 加载 LUKS 密码,然后返回键盘?

    我想设置一台具有全磁盘加密功能的无头 Linux Debian Wheezy PC 能够使用 USB 驱动器或通过键盘输入密码来解锁磁盘 我的起点是使用 Debian 安装程序中基本的整个磁盘加密选项进行全新安装 该安装程序将 boot 之
  • 如何在 Square MockWebServer 中使用 SSL?

    我尝试启用 SSLSquare 的 MockWebServer https github com square okhttp tree master mockwebserver在测试下模拟我的 Android 应用程序中的所有 Web 服务
  • 如何使用 PowerShell 递归合并/“展平”文件夹结构

    我正在寻求帮助来重组许多子文件夹中的大量文件 示例来源 folderX aaa txt bbb txt folderY ccc txt folderZ ddd txt eee txt 理想结果 folderX aaa txt folderX
  • 自上一步以来进程或线程已更改

    我正在 Visual Studio 上调试一些代码 此代码属于我创建的自定义会话提供程序 我正在 Web 应用程序启动时对其进行调试 它开始初始化我的提供程序 并且在该函数上我有一个第一次成功命中的断点 但是 同一断点再次被击中 但它有一个
  • 带有自定义离线页面的 Angular PWA

    在 Angular 8 应用程序中 我想添加一个自定义离线页面 只是一个简单的 html 文件 我已将我的应用程序设置为 PWA 使用 angular pwa并配置了一切 以便它至少在在线时顺利工作 然而 我很难为 PWA 用户提供更新 因
  • unsafePerformIO 和 FFI 库初始化

    我正在为 C 中的库创建一个 FFI 模块 该模块希望在执行其他操作之前调用一个一次性 不可重入的函数 这个调用是幂等的 但是有状态的 所以我可以在每个 Haskell 调用中调用它 但它很慢 并且由于不可重入 可能会导致冲突 那么现在是使
  • 允许用户在 Android 应用程序中插入图像

    我的问题是 如何创建 imageButton 允许用户从手机上传图像并将其作为图片配置文件插入应用程序中 例如 像 Whatsapp 一样 它允许用户从手机中选择图像并将其设置为图片配置文件 Thanks 我的 XML 文件
  • 为什么 Func 与 Func> 不明确?

    这个问题让我很困惑 所以我想我会在这里问 希望 C 大师可以向我解释一下 为什么这段代码会产生错误 class Program static void Main string args Foo X the error is on this
  • Laravel 5.3 存储和读取文件目录

    目前正在尝试处理文件 但很难弄清楚将它们放在哪里以及如何在列表中读回它们 我尝试过将一些测试文件放入 files array dir opendir asset files open the cwd also do an err check
  • 如何使用 pyspark 从 s3 存储桶读取 csv 文件

    我正在使用 Apache Spark 3 1 0 和 Python 3 9 6 我正在尝试从 AWS S3 存储桶读取 csv 文件 如下所示 spark SparkSession builder getOrCreate file s3 b
  • 不获取AudioListenerInterruptionEnd触发器

    我对 OpenAl 和 MPMoviePlayerController 的组合有疑问 我在 OpenAl 设置过程中注册了 AudioInterruptionLister 当我开始播放视频时 侦听器会收到 AudioListenerInte
  • 离子 3 角度 4 动画不起作用

    我有一个组件 我正在尝试为手风琴列表设置动画 我已经进行了所有更改 例如包括import BrowserModule from angular platform browser and import BrowserAnimationsMod
  • std::unordered_set 迭代器遍历的复杂性

    我最近玩了一个std unordered set http en cppreference com w cpp container unordered set 我怀疑我的 STL 版本会跟踪某些 FILO 数据结构 看起来像列表 中的非空存