我想存储字符串并为每个字符串分配一个唯一的ID号(索引就可以了)。我只需要每个字符串的一个副本,我需要快速查找。我经常检查表中是否存在字符串,以至于我注意到了性能损失。什么是最适合使用的容器,如果字符串存在,我该如何查找?
答案 0 :(得分:9)
我建议使用tr1 :: unordered_map。它被实现为散列映射,因此它具有用于查找的O(1)的预期复杂度以及O(n)的最坏情况。如果您的编译器不支持tr1,还有一个boost实现。
#include <string>
#include <iostream>
#include <tr1/unordered_map>
using namespace std;
int main()
{
tr1::unordered_map<string, int> table;
table["One"] = 1;
table["Two"] = 2;
cout << "find(\"One\") == " << boolalpha << (table.find("One") != table.end()) << endl;
cout << "find(\"Three\") == " << boolalpha << (table.find("Three") != table.end()) << endl;
return 0;
}
答案 1 :(得分:7)
试试这个:
(来源:adrinael.net)
答案 2 :(得分:5)
尝试std :: map。
答案 3 :(得分:4)
首先您必须能够量化您的选择。您还告诉我们您感兴趣的主要使用模式是查找,而不是插入。
让N
为您希望在表格中使用的字符串数量,并让C
为所述表格中任何给定字符串中的平均字符数(或者在根据表格检查的字符串中。
对于基于哈希的方法,对于每次查询,您需要支付以下费用:
O(C)
- 计算您要查找的字符串的哈希值O(1 x C)
和O(N x C)
之间,其中1..N
是您希望基于散列密钥遍历存储桶的成本,此处乘以C
以重新检查字符在每个字符串中对着查找键O(2 x C)
和O((N + 1) x C)
如果是基于 std::map
的方法(使用红黑树),则每次查询都需要支付以下费用:
O(1 x C)
和O(log(N) x C)
之间 - 其中O(log(N))
是最大树遍历费用,O(C)
是std::map
的通用时间less<>
实现需要在树遍历期间重新检查查找键如果N
的值很大,并且没有散列函数可以保证少于log(N)的碰撞,或者你只是想安全地玩,你会更好使用基于树的(std::map
)方法。如果N很小,一定要使用基于散列的方法(同时仍然确保哈希冲突很低。)
在做出任何决定之前,您还应该检查:
答案 4 :(得分:2)
听起来像一个数组在索引是数组索引的地方就可以了。要检查它是否存在,只需确保索引位于数组的边界内,并且其条目不是NULL。
编辑:如果您对列表进行排序,您可以始终使用应该快速查找的二进制搜索。
编辑:此外,如果您要搜索字符串,也可以始终使用std::map<std::string, int>
。这应该有一些不错的查找速度。
答案 5 :(得分:2)
是否可以静态搜索字符串?您可能希望查看perfect hashing function
答案 6 :(得分:1)
最简单的方法是使用std :: map。
它的工作原理如下:
#include <map>
using namespace std;
...
map<string, int> myContainer;
myContainer["foo"] = 5; // map string "foo" to id 5
// Now check if "foo" has been added to the container:
if (myContainer.find("foo") != myContainer.end())
{
// Yes!
cout << "The ID of foo is " << myContainer["foo"];
}
// Let's get "foo" out of it
myContainer.erase("foo")
答案 7 :(得分:0)