【问题标题】:C++ hash table w/o using STL不使用 STL 的 C++ 哈希表
【发布时间】:2011-02-21 10:51:26
【问题描述】:

我需要创建一个哈希表,其中键为字符串,值为 int。我不能在我的目标上使用 STL 容器。是否有适合此目的的哈希表类?

【问题讨论】:

  • 可以使用什么?您是否正在寻找有关实现哈希表或替代现有实现的提示?
  • 你最好有一个非常好的理由不使用 STL。这可能是家庭作业吗?
  • 目标这个词对我来说意味着某种嵌入式系统。
  • @^%#@%^!# - 我为这个家伙编写了一个不错的小哈希添加/删除函数,没有模板,网站出现故障并杀死了我所有的代码。瘸!跛脚!
  • @Michael: Firefox + TextArea Cache.

标签: c++ data-structures hashtable


【解决方案1】:

您可以使用来自 Boost 的 unordered associative container,又名。 boost::unordered_map根据哈希表实现的。

【讨论】:

  • 虽然发帖者反对 STL 的内容会很有趣。如果确实使用了模板,那么 boost 也被淘汰了。
  • @mjmarsh:是的,但在这种情况下,更多信息会有所帮助。就我而言,即使排除 STL 也是一个不合理的要求,但由于没有提到其他限制,我认为使用 Boost 库可能是显而易见的选择。
【解决方案2】:

这是一个有争议的问题,因为 STL 没有哈希表容器; std::map 将是替代方案。对于大多数目的,没有理由不使用 std::map。对于需要哈希表的用途,boost::unordered_map 是最佳选择(我认为与新 C++ TR1 提议标准中定义的哈希表相匹配。一些编译器——但我不能命名它们——可能会提供 TR1 哈希表为std::tr1::unordered_map

【讨论】:

    【解决方案3】:

    【讨论】:

      【解决方案4】:

      如果您提前知道您的键列表(或其某些超集),您可以使用perfect hash function 生成器,例如@987654322@gperf 会输出 C 或 C++ 代码。

      (不过,考虑到哈希函数,您可能需要做一些工作才能真正构建容器。)

      【讨论】:

        【解决方案5】:

        这是我刚刚写的一个快速的脏 C 哈希。编译,但在本地未经测试。尽管如此,您仍然可以根据需要使用它。其性能完全取决于 keyToHash 函数。我的版本不会是高性能的,但会再次演示如何做到这一点。

        
        static const int kMaxKeyLength = 31;
        static const int kMaxKeyStringLength = kMaxKeyLength + 1;
        
        struct HashEntry
        {
          int value;
          char key[kMaxKeyLength];
        };
        
        static const char kEmptyHash[2] = "";
        
        static const int kHashPowerofTwo = 10;
        static const int kHashSize = 1 &lt&lt kHashPowerofTwo;
        static const int kHashMask = kHashSize - 1;
        
        static const int kSmallPrimeNumber = 7;
        
        static HashEntry hashTable[kHashSize];
        
        int keyToHash(const char key[])
        {
          assert(strlen(key) &lt kMaxKeyLength);
        
          int hashValue = 0;
          for(int i=0; &lt strlen(key); i++)
          {
            hashValue += key[i];
          }
        
          return hashValue;
        }
        
        bool hashAdd(const char key[], const int value)
        {
          int hashValue = keyToHash(key);
        
          int hashFullSentinal = 0;
          while(strcmp(hashTable[hashValue & kHashMask].key, kEmptyHash))
          {
            hashValue += kSmallPrimeNumber;
        
            if(hashFullSentinal++ &gt= (kHashSize - 1))
            {
              return false;
            }
          }
        
          strcpy(hashTable[hashValue & kHashMask].key, key);
          hashTable[hashValue & kHashMask].value = value;
        
          return true;
        }   
        
        bool hashFind(const char key[], int *value)
        {
          int hashValue = keyToHash(key);
        
          while(strcmp(hashTable[hashValue & kHashMask].key, kEmptyHash))
          {
            if(!strcmp(hashTable[hashValue & kHashMask].key, key))
            {
              *value = hashTable[hashValue & kHashMask].value;
              return true;
            }
          }
        
          return false;
        }
        
        bool hashRemove(const char key[])
        {
          int hashValue = keyToHash(key);
        
          while(strcmp(hashTable[hashValue & kHashMask].key, kEmptyHash))
          {
            if(!strcmp(hashTable[hashValue & kHashMask].key, key))
            {
              hashTable[hashValue & kHashMask].value = 0;
              hashTable[hashValue & kHashMask].key[0] = 0;
              return true;
            }
          }
        
          return false;
        }
        
        

        【讨论】:

          【解决方案6】:

          如果您需要最高性能,请使用MCT's closed_hash_mapGoogle's dense_hash_map。前者更容易使用,后者更成熟。您的用例听起来会从封闭哈希中受益。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2011-08-04
            • 1970-01-01
            • 2020-08-31
            • 2011-08-17
            • 2011-01-12
            • 1970-01-01
            • 2011-02-01
            • 1970-01-01
            相关资源
            最近更新 更多