【问题标题】:How can I reference a substr without creating a new object?如何在不创建新对象的情况下引用 substr?
【发布时间】:2014-03-30 22:17:21
【问题描述】:

我有几个长度为 2000 - 3000 个字符的字符串,我想将每个长度为 X 的子字符串散列到一个 unordered_multimap。因此,我逐个字符地遍历每个字符串以确定每个哈希值。 substr 函数创建一个新字符串,将 std::pair 插入到多重映射中也是如此。我想尽量避免。有没有办法解决这个问题?

伪代码示例:

For each String str:
    For i to str.length - hashlength
        hash = str.substr(i, hashlength) //A
        unordered_multimap.insert({{hash, i}}); //B

我希望 A 和 B 部分使用尽可能少的构造函数调用。

【问题讨论】:

  • 启用C++11并将哈希声明为string&&
  • 如果 hash 是 std::string 你可以在循环中重用然后你调用 use hash.assign(str.begin() + i, str.begin() + i + hashlength) 并且至少保存一个分配。
  • 如果要将其存储在地图中,则至少需要一个构造
  • @texasbruce 这有什么帮助?
  • 你可以存储一对迭代器

标签: c++ string hashmap hashtable


【解决方案1】:

有几个库允许您执行此操作。比如boost::string_refllvm::StringRef。一个类似的类,string_viewboost::string_ref 是基于它的),正在为未来的标准化而工作。如果您不想下载另一个库,该类的实现相当简单。它只不过是一个 const char* 来指示子字符串的开始,一个整数来指示长度(或者,另一个指针来指示结束点),以及一些实用函数。

对于所有这些类,需要注意的一个共同点是,只要使用引用对象,您就需要确保源字符串保持活动状态且未修改(或至少确保不会发生重新分配)。换句话说,像对待指针一样小心对待它们(因为它们本质上就是这样)。

【讨论】:

  • 这需要重写hashcode函数吗?
  • @whytheman:是的,除非您使用为您提供散列函数的库。我相信llvm::StringRef 会,而且我确信(或至少我希望)string_view 在标准化后会。
  • string_view 已经包含在 c++17 中,那么这是最好的选择
猜你喜欢
  • 2012-04-14
  • 2021-12-20
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-10
  • 2021-09-16
  • 2022-11-30
相关资源
最近更新 更多