是否可以比使用 hashmap 更快地将字符串映射到 int?

2024-02-17

我知道我不应该优化程序的每个点,所以请考虑这个问题是“学术”的

我最多有 100 个字符串和每个字符串的整数,如下所示:

MSFT 1
DELL 2
HP   4
....
ABC  58

该集合是预先初始化的,这意味着一旦创建它就永远不会改变。设置初始化后,我会非常频繁地使用它,因此快速查找很不错。字符串非常短,最多 30 个字符。映射int也有限制,在 1 到 100 之间。

至少知道字符串是预先初始化的并且永远不会改变,应该可以“找到”导致“一篮子一项目”映射的散列函数,但可能还有其他黑客。

我可以想象的一个优化 - 我只能读取第一个符号。例如,如果“DELL”是唯一以“D”开头的字符串,并且我收到了类似“D***”的内容,那么我什至不需要读取该字符串!显然是“DELL”。这种查找必须比“哈希图查找”快得多。 (这里我假设我们只收到哈希中的符号,但情况并非总是如此)

有没有现成的或易于实施的解决方案来解决我的问题?我正在使用 c++ 和 boost。

upd我查了一下,发现我的股票交易限额是 12 个符号,而不是上面提到的 30 个。然而,其他交易所可能允许稍长的符号,因此拥有能够继续处理长达 20 个字符的代码的算法很有趣。


A hashtable[1] is in principle the fastest way.

You could然而编译一个完美的哈希函数 http://en.wikipedia.org/wiki/Perfect_hash_function鉴于您提前知道完整的域名这一事实。

有了完美的哈希,就不需要发生冲突,因此您可以将哈希表存储在线性数组中!

通过适当的调整,您可以

  • 将所有哈希元素放入有限的空间中,使直接寻址成为一种潜在的选择
  • 在 O(1) 内进行反向查找

用于生成完美哈希函数的“老式”工具是gperf(1) http://www.gnu.org/software/gperf/。维基百科列出了有关该主题的更多资源。

因为所有的争论我运行了一个演示:

正在下载并从该集中获取 100 个随机样本,应用 gperf 如下:

gperf -e ' \015' -L C++ -7 -C -E -k '*,1,$' -m 100 selection > perfhash.cpp

结果哈希值 MAX_HASH_VALUE 为157 and a direct尽可能多的项目的字符串查找表。这是just用于演示目的的哈希函数:

inline unsigned int Perfect_Hash::hash (register const char *str, register unsigned int len) {
  static const unsigned char asso_values[] = {
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156,  64,  40,   1,  62,   1,
       41,  18,  47,   0,   1,  11,  10,  57,  21,   7,
       14,  13,  24,   3,  33,  89,  11,   0,  19,   5,
       12,   0, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156, 156,
      156, 156, 156, 156, 156, 156, 156, 156, 156
    };
  register int hval = len;

  switch (hval) {
      default: hval += asso_values[(unsigned char)str[4]];   /*FALLTHROUGH*/
      case 4:  hval += asso_values[(unsigned char)str[3]];   /*FALLTHROUGH*/
      case 3:  hval += asso_values[(unsigned char)str[2]+1]; /*FALLTHROUGH*/
      case 2:  hval += asso_values[(unsigned char)str[1]];   /*FALLTHROUGH*/
      case 1:  hval += asso_values[(unsigned char)str[0]];   break;
  }
  return hval;
}

它确实没有变得更有效率。请看一下完整源代码位于 github:https://gist.github.com/sehe/5433535 https://gist.github.com/sehe/5433535

请注意,这也是一个完美的哈希,所以会有没有碰撞


Q. [...] 显然是“DELL”。这种查找必须比“哈希图查找”快得多。

A:如果你使用一个简单的std::map最终效果是前缀搜索(因为第一个字符不匹配的字典字符串比较快捷方式)。在排序容器中进行二分查找也是如此。


[1] PS. For 100 strings, a sorted array of string with std::search or std::lower_bound would potentially be as fast/faster due to the improved Locality of Reference http://en.wikipedia.org/wiki/Locality_of_reference. Consult your profile results to see whether this applies.

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

是否可以比使用 hashmap 更快地将字符串映射到 int? 的相关文章

随机推荐

  • 如何渲染所选对象的数据?

    目前正在尝试学习使用 firebase 进行反应 并不断遇到一些小障碍 截至目前 我正在尝试在新页面中呈现所选项目的数据 索引页包含以下内容 renderPosts return Object keys this state posts m
  • Eclipse WTP 部署构建路径依赖项

    我有一个依赖于其他项目 项目属性 Java 构建路径 项目 的 Eclipse 项目 并且这些其他项目导出自己的库 项目属性 Java 构建路径 顺序和导出 有没有办法让 Eclipse WTP 和 或 JBoss Tools 将依赖项目的
  • 您最近提交的应用因违反 Google Play 开发者计划政策而被拒绝

    1 我的应用程序简单的教育基础内容和测试尝试 2 没有任何谷歌广告 只有一个 youtube 集成 这个简单的应用程序 通过学院提供的激活密钥登录 Google 发送邮件应用程序拒绝 我不明白为什么 问题 违反家庭政策要求 包含吸引儿童的元
  • 我如何告诉 Solr 返回每个文档的命中搜索词?

    我对 Solr 中的查询有疑问 当我使用多个搜索词执行查询时 这些搜索词全部由 OR 逻辑链接 例如q content foo OR bar OR foobar 比 Solr 返回所有与这些术语匹配的文档列表 但 Solr 做了什么not返
  • 从动态 GUI 中的 Gtk 视口/滚动窗口中删除小部件

    我正在构建一个 GUI GTK3 的 Python 绑定 其中一个 Gtk 滚动窗口 来自 Glade 可以包含不同的树视图 该程序启动时有一个空窗口 第一次一切正常 self scrolled window add with viewpo
  • cuda.h、cuda_runtime.h、cuda_runtime_api.h 之间的区别

    我开始使用 CUDA 进行编程 在一些示例中我找到了包含文件cuda h cuda runtime h and cuda runtime api h包含在代码中 有人可以向我解释一下这些文件之间的区别吗 从非常广泛的角度来说 cuda h定
  • PySimpleGUI 如何在图像顶部放置按钮

    这是带有图像和 图像作为按钮 的示例 但我想在图像上放置一个小按钮 可以吗 使用普通的 python 我可以使用 image place 40 40 方法来做到这一点 以及如何使用 PySimpleGUI 来做到这一点 import PyS
  • 替换列表元素是反模式吗?

    我有一个适用于以列表表示的路径的模块 大多数函数都会执行典型的递归列表处理 但现在我需要一个有时会改变路径的函数 所以 我写了这个replace功能 module List let replace f sub xs let rec fini
  • LINQ 查询数据表以检查记录是否存在

    我想对名为 Records 的数据表执行 LINQ 查询并检查记录是否存在 如果它存在 我想找出它所在的行 我该怎么做呢 添加 system linq 命名空间后 我想在数据表上执行 where 操作 但该方法似乎不存在 请指教 PS 我在
  • 什么设置决定应用程序是否针对 iPhone 6 和 6plus 进行缩放?

    因此 当我在 iPhone 6 模拟器上运行我的项目时 部署目标为 7 1 我希望所有内容都能自动缩放以适应更大的屏幕尺寸 但这并没有发生 我的 UILabel 以前水平位于 320 像素宽的情节提要屏幕的中心 对父视图具有领先的空间限制
  • RStudio 控制台中带有日期列输出的 data.frame,预览,但不低于块

    使用 Rstudio 3 3 2 的笔记本 title R Notebook output html notebook 当尝试显示 data frame 时日期栏 data frame 显示在查看器选项卡中 但不在块本身下方 r df lt
  • 如何使用 Facebook SDK 3.1 以弹出视图登录 facebook,而不是通过 safari? [关闭]

    很难说出这里问的是什么 这个问题是含糊的 模糊的 不完整的 过于宽泛的或修辞性的 无法以目前的形式得到合理的回答 如需帮助澄清此问题以便重新打开 访问帮助中心 help reopen questions 请帮我解答这个问题 我想创建应用程序
  • clang-format:类声明结束和命名空间关闭之间的空行

    我使用 clang format 来格式化我们的 C 代码 我想在类声明和周围命名空间的右大括号之间有一个空行 如下所示 namespace Foo class Bar 但 clang format 将我的代码更改为 namespace F
  • 如何检查文本框是否为空

    在一个网站上我发现了TryParse方法 如何检查C 中是否有空文本框 但我不知道如何使用它 int outputValue 0 bool isNumber false isNumber int TryParse textBox1 Text
  • 安装 Forge Installer - 自动启动安装程序

    我正在使用 InstallForge 创建安装程序 我希望创建一个安装程序 该安装程序将在启动时自动启动已安装的程序 我认为安装程序可以在启动文件夹中创建快捷方式 并且该程序应该在启动时加载 我用谷歌搜索并找到了解决方案 但当我尝试时却不起
  • jboss as 7 - 在同一Linux服务器中运行多个实例 - 独立与域

    我下载了 jboss tar 文件 复制到我的测试服务器中 解压并将其安装在 HOME jboss 现在 我需要在一台服务器上同时运行三个实例 开发 QA UAT Domain模式适合这种情况吗 我的结论是事实并非如此 域模式是跨多个服务器
  • git pull --rebase 通过保留本地更改来解决冲突

    我在当地分支机构重新获得了硕士学位 与此同时 有人在远程对该分支进行了更改 我在做git pull rebase 我不明白 git 在命名时如何解释这个命令current and incoming 也ours and theirs 我应该选
  • 使用 terraform aws_acm_certificate_validation 时缺少 DNS 验证记录

    在尝试创建 AWS Route53 资源和 AWS Certificate Manager 资源时 我一整天都陷入 Terraform 错误 这 2 位是一个更广泛的项目的一部分 通过其静态服务功能托管在 s3 中的网站 具体来说 当 CN
  • iphone中出现键盘时如何显示标签栏

    大家好 我正在一个基于选项卡栏的应用程序中工作 我需要显示键盘 键盘通常出现 但我希望应该显示我的选项卡栏 并且在选项卡栏上方只有键盘应该显示如何完成此操作 谢谢你们 您可以将选项卡栏与键盘一起移动 如下所示 IBAction textBo
  • 是否可以比使用 hashmap 更快地将字符串映射到 int?

    我知道我不应该优化程序的每个点 所以请考虑这个问题是 学术 的 我最多有 100 个字符串和每个字符串的整数 如下所示 MSFT 1 DELL 2 HP 4 ABC 58 该集合是预先初始化的 这意味着一旦创建它就永远不会改变 设置初始化后