2014-03-30 150 views
3

我有几个字符串的长度为2000 - 3000个字符,我想将长度为X的每个子字符串散列为一个unordered_multimap。因此,我逐字符遍历每个字符串以确定每个散列。 substr函数创建一个新的字符串,并且将一个std :: pair插入到multimap中。我想尽可能避免。有没有办法解决这个问题?如何在不创建新对象的情况下引用substr?

伪码示例:

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

我宁愿有A和B部分使用尽可能少的构造函数调用越好。

+0

启用C++ 11并将hash声明为'string &&' – texasbruce

+1

如果hash是一个'std :: string',您可以在循环中重用,那么您可以调用use'hash.assign(str.begin()+ i,str .begin()+ i + hashlength)'并且至少保存一个分配。 –

+0

如果你想将它存储在地图中,那么至少需要**一**结构 – Paranaix

回答

6

有几个库可以让你做到这一点。如boost::string_refllvm::StringRef。类似的课程string_view(其中boost::string_ref基于此课程)正在进行未来标准化工作。如果你不想下载另一个库,那么这个类很容易实现。它只是指示子字符串的起始处的一个const char*,以及指示长度的整数(或者指示终点的另一个指针)以及一些实用函数。

所有这些类都需要注意的一个常见事情是,只要使用引用对象,就需要确保源字符串保持活动且未修改(或者至少确保不发生重新分配) 。换句话说,对待它们的方式与指针相同(因为它本质上就是它们的意思)。

+0

这是否需要重写hashcode函数? – whytheman

+0

@whytheman:是的,除非您使用为您提供散列函数的库。我相信'llvm :: StringRef'确实,并且我确信(或者至少我希望)'string_view'将会在标准化时被使用。 –

+0

string_view已经包含在C++ 17中,那么这是最好的选择 – Tecoberg

相关问题