c++ - 高效的字符串到 unordered_map 中的键匹配?

标签 c++ regex c++11 string-matching unordered-map

将这些字符串映射到函数的最有效方法是哈希表:

std::string a="/foo/", b="/foo/car/", c="/foo/car/can/", d="/foo/car/haz/";

不幸的是,当您想要匹配最简单的模式时,事情会变得更加复杂:

/foo/[a-Z|0-9]+>/
/foo/[a-Z|0-9]+>/bar/[a-Z|0-9]+/

有人告诉我 <regex>图书馆对我的需求来说太过分了;而且它的开销是相当大的。

在这里使用哈希表(std::unordered_map)可能是一个有效的选择;与 [a-Z|0-9]+在开关/案例中的单个解析中进行检查。参数的数量(拆分为 / )和使用 / 的数量然后任意数量的参数来决定采用哪条路径:

"/foo/"                  => {<function>, "/foo/can/", "/foo/[a-Z|0-9]+/bar/"}
"/foo/xflkjkjc34v"       => {<function>, "/foo/can/", "/foo/[a-Z|0-9]+/bar/"}
"/foo/can"               => {<function>, "/foo/can/", "/foo/[a-Z|0-9]+/bar/"}
"/foo/vxcvxc86vzxc/bar/" => {<function>, "/foo/[a-Z|0-9]+/bar/haz"}

可以实现;但这是最好的方法吗?

最佳答案

一个理想的数据结构是一个 trie,其中每个斜杠分隔的段与 unordered_map 或什至排序的 vector 中的第一个和最后一个无通配符的字符串匹配(这可以分别在 O(1) 或 O(logN) 中完成),然后如果没有找到匹配项的 vector 正则表达式(您可能需要一个一个地尝试 - O (N))。根据您的性能需求,您可以通过将常量字符串视为正则表达式并始终在 trie 中的每个节点进行 O(N) 搜索来简化事情。

+----------+     +---------------+                   +-----------+
| fixed:   |     | fixed:        |                   | fixed:    |
|    foo  -+---->|    bar       -|---> fn_foo_bar  --|   xxx    -|---> fn_foo_X_xxx
|    abc  -+-    |               |                /  |           |
| regexp:  | \   | regexp:       |               /   | regexp:   |
+----------+  |  |    [A-Z0-9]+ -|---------------    +-----------+
              |  +---------------+
              |
              \->+---------------+
                 | fixed:        |
                  ...

如果您对固定和正则表达式组件的潜在变体数量有更具体的了解,您很可能能够进一步优化它,但这是具有合理可扩展性的通用解决方案。

关于c++ - 高效的字符串到 unordered_map 中的键匹配?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22901501/

相关文章:

c# - ZeroMq recv 不阻塞

c++ - 获取Windows版本

c++ - 将右值分配给 'const auto&' 时会发生什么

c++ multimap equal_range 一无所获

c++ - 具有单个元素的结构的大小

Python:将驼峰大小写转换为使用正则表达式分隔的空格并考虑首字母缩略词

c# - 员工 ID 的标准正则表达式

javascript - 使用正则表达式将最后一个逗号分隔值替换为另一个值

c++ - 对带有可变参数模板的 std::ref() 和 std::bind() 有点模糊

c++ - C++ `unordered_set` 中两个 "not working"的交集在类方法中但可与 `set` 一起使用?