dense_hash_map的复杂key的用法

比较了std::map和boost::unordered_map; 后者性能略胜前者。

准备使用dense_hash_map试试。

简单的例子见http://www.cnblogs.com/dreamcs/articles/1782340.html

官方的例子有

#include <iostream>
#include <google/dense_hash_map>

using google::dense_hash_map;      // namespace where class lives by default
using std::cout;
using std::endl;
using ext::hash;  // or __gnu_cxx::hash, or maybe tr1::hash, depending on your OS

struct eqstr
{
  bool operator()(const char* s1, const char* s2) const
  {
    return (s1 == s2) || (s1 && s2 && strcmp(s1, s2) == 0);
  }
};

int main()
{
  dense_hash_map<const char*, int, hash<const char*>, eqstr> months;
  
  months.set_empty_key(NULL);
  months["january"] = 31;
  months["february"] = 28;
  months["march"] = 31;
  months["april"] = 30;
  months["may"] = 31;
  months["june"] = 30;
  months["july"] = 31;
  months["august"] = 31;
  months["september"] = 30;
  months["october"] = 31;
  months["november"] = 30;
  months["december"] = 31;
  
  cout << "september -> " << months["september"] << endl;
  cout << "april     -> " << months["april"] << endl;
  cout << "june      -> " << months["june"] << endl;
  cout << "november  -> " << months["november"] << endl;
}

  起初因为很好用,很简单的例子嘛。但是我的项目里面是一用一对string作为key的,换了一把不好使。

不知道这个dense_hash_map怎么用了,晕菜。

To: google-sparsehash@googlegroups.com
Subject: Re: std::pair usage in google sparse hash
References: <e403a8fc-b94b-45eb-bc32-3cdcad1d9...@s21g2000prm.googlegroups.com>
From: Craig Silverstein <csilv...@google.com>
Date: Fri, 11 Sep 2009 14:38:13 -0700
In-Reply-To: <e403a8fc-b94b-45eb-bc32-3cdcad1d9...@s21g2000prm.googlegroups.com> (Shankar's message of "Fri\, 11 Sep 2009 14\:34\:31 -0700 \(PDT\)")
Message-ID: <m3ljklduwq....@meta.mtv.corp.google.com>
User-Agent: Gnus/5.11 (Gnus v5.11) Emacs/22.1 (gnu/linux)
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
X-System-Of-Record: true

} Is there an alternative implementation which doesnot use std::pair ?

There is not.  However, sparse_hash_map is a pretty thin wrapper
around sparsehashtable.  You could write your own wrapper around
sparsehashtable with not that much code, and replace pair<> with the
data structure of your choice.  I don't think you'll need to modify
the sparsehashtable code at all.

直到我发现了http://code.google.com/p/google-sparsehash/issues/detail?id=58&can=1,调试了一把,发现可以,于是我猜测单单实现一个比较器不行,必须自己实现一个pair的hash。于是搞定了。

inline unsigned int BKDRHash(const string& str, const string& str2)
{
   unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
   unsigned int hash = 0;

   for(std::size_t i = 0; i < str.size(); i++)
   {
      hash = (hash * seed) + str[i];
   }
   hash = (hash * seed) + '\t';
    for(std::size_t i = 0; i < str2.size(); i++)
   {
      hash = (hash * seed) + str2[i];
   }
   return hash;
}


struct pairKeyHash
{
	size_t operator()(const pair<string,string>& p1) const
	{
		return BKDRHash(p1.first, p2.second);
	}
};

struct pairKeyEq
{
	size_t operator()(const pair<string,string>& p1, const pair<string,string>& p2) const
	{
		return p1 == p2;
	}
};


int main()
{
  dense_hash_map<const string, string,  pairKeyHash, pairKeyEq > test_map;
  test_map.set_empty_key(make_pair("",""));

  test_map[make_pair("1","1")] = "A";

  
  cout << "1 -> " << months[make_pair("1","1")] << endl;
  return 0;
}

搞定了,不过测试起来没看出这个map有多快,哎,难道是我的hash算法不行!

原文地址:https://www.cnblogs.com/hero4china/p/dense_hash_map.html