C++ 用于快速名称查找的容器

C++ 用于快速名称查找的容器,c++,containers,std,C++,Containers,Std,我想存储字符串,并给每个字符串分配一个唯一的ID号(索引就可以了)。我只需要每个字符串的一个副本,我需要快速查找。我经常检查该字符串是否存在于表中,以至于我注意到性能受到了影响。用于此目的的最佳容器是什么?如果字符串存在,我如何查找?我建议使用tr1::无序映射。它是作为hashmap实现的,因此对于查找,它的预期复杂性为O(1),最坏情况为O(n)。如果您的编译器不支持tr1,那么还有一个boost实现 #include <string> #include <iostream

我想存储字符串,并给每个字符串分配一个唯一的ID号(索引就可以了)。我只需要每个字符串的一个副本,我需要快速查找。我经常检查该字符串是否存在于表中,以至于我注意到性能受到了影响。用于此目的的最佳容器是什么?如果字符串存在,我如何查找?

我建议使用tr1::无序映射。它是作为hashmap实现的,因此对于查找,它的预期复杂性为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;
}
#包括
#包括
#包括
使用名称空间std;
int main()
{
tr1::无序的_映射表;
表[“一”]=1;
表[“两”]=2;

cout听起来,如果索引是数组中的索引,那么数组就可以正常工作。要检查它是否存在,只需确保索引在数组的边界内,并且其条目不为NULL

编辑:如果对列表进行排序,则始终可以使用二进制搜索,该搜索应具有快速查找功能


编辑:另外,如果您想搜索字符串,也可以使用
std::map
。这应该有一些不错的查找速度。

试试std::map。

要搜索的字符串是否静态可用?您可能想查看最简单的方法是使用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")
#包括
使用名称空间std;
...
地图容器;
myContainer[“foo”]=5;//将字符串“foo”映射到id 5
//现在检查是否已将“foo”添加到容器中:
if(myContainer.find(“foo”)!=myContainer.end()
{
//对!!

cout首先,您必须能够量化您的选项。您还告诉我们,您感兴趣的主要使用模式是查找,而不是插入

假设
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
      的通用
      实现在树遍历期间重新检查查找键所需的时间
  • 如果
    N
    的值较大,并且没有保证少于日志(N)冲突的哈希函数,或者如果您只是想安全起见,最好使用基于树的(
    std::map
    )方法。如果N较小,请务必使用基于哈希的方法(同时仍然确保哈希冲突较低。)

    但是,在做出任何决定之前,您还应该检查:

      • 也许

        试试这个:



        (来源:)

        等等,你想说存在(“我的字符串”)?我想你想说的是:C[index]获取字符串。正如我对@Teran的答案所做的评论:不是吗?他想在给定UID的情况下查找,而不是字符串。他说他想在对Teran答案的评论中通过字符串查找,如果我答对了,那么他没有……但我们猜他做到了:)不要在T1中使用无序_映射,它没有reserve方法,如果在插入阶段插入了大量字符串,则将进行大量的重新灰化。此外,长字符串的无序_映射比std::map更糟糕