hash_map使用自定义类型做主键

unordered_set

unordered_map

template < class Key,                                    // unordered_map::key_type
           class T,                                      // unordered_map::mapped_type
           class Hash = hash<Key>,                       // unordered_map::hasher
           class Pred = equal_to<Key>,                   // unordered_map::key_equal
           class Alloc = allocator< pair<const Key,T> >  // unordered_map::allocator_type
           > class unordered_map;


方法1:

class InnerP2PString;

typedef std::tr1::shared_ptr<InnerP2PString> P2PString;


class InnerP2PString {

public:


  InnerP2PString(const uint8_t *val, uint16_t len);

  InnerP2PString(const std::string &val);

  ~InnerP2PString();

  std::string val_;

  uint32_t use_times_;

};


typedef std::tr1::unordered_set<P2PString> FileMap;

typedef std::tr1::unordered_map<P2PString, uint32_t> FileTracks;


现在使用的类是P2PString,作为hash_map主键,需要重载一下操作符

namespace std {

  namespace tr1 {

    template<>

    struct hash<P2PString>

      : public std::unary_function<std::string, std::size_t> {

      std::size_t

      operator()(const P2PString& s) const {

        // return Fnv_hash<>::hash((char*)s->val_.data(), s->val_.length()); 

        const char* first = s->val_.data();

        std::size_t length = s->val_.length();

        std::size_t result = static_cast<std::size_t>(14695981039346656037ULL);

        for (; length > 0; --length) {

          result ^= (std::size_t)*first++;

          result *= 1099511628211ULL;

        }

        return result;

      }

    };

  }

  

  template <>

  struct equal_to<P2PString> : public binary_function<P2PString, P2PString, bool>

  {

    bool

    operator()(const P2PString& __x, const P2PString& __y) const

    { return __x->val_ == __y->val_; }

  };

  template <>

  struct less<P2PString> : public binary_function<P2PString, P2PString, bool>

  {

    bool

    operator()(const P2PString& __x, const P2PString& __y) const

    { return __x->val_ < __y->val_; }

  };

}

方法2:

struct KeyPidInfo
{
char key[32];
int pid;

    bool operator<(const KeyPidInfo &keyPid) const
    {
       int flag = strcmp(this->key, keyPid.key);
           return (flag < 0) || 
                   ((flag == 0) && (this->pid < keyPid.pid));
    }

};

struct Hash_KeyPidInfo

    size_t operator()(const KeyPidInfo &keyPidInfo) const
    { 
       char tmp[42];
       int len = strlen(keyPidInfo.key);
       strcpy(tmp, keyPidInfo.key);
       string pid;
       pid = lexical_cast<string>(keyPidInfo.pid);
       strcpy(tmp + len, pid.c_str());
       hash<char *> ht;//直接用了已经提供的hah函数,没有自己编写hash
       return ht(tmp); 
    }
};

struct Equal_KeyPidInfo
{
    bool operator()(const KeyPidInfo &left, const KeyPidInfo &right) const
    {
        return (strcmp(left.key, right.key) == 0) && (left.pid == right.pid);
    }
};

用的时候这样定义:

unordered_map<KeyPidInfo, int, Hash_KeyPidInfo, Equal_KeyPidInfo> valueMap;

备注:

class Thing {

public:

bool operator== (const Thing&) const;

};

struct Hash_Thing {

// hash function object class for Thing

std::size_t operator() (const Thing& t) const

{ /* compute and return a size_t value using some property of Thing */}

};

unordered_set<Thing, Hash_Thing> uset_of_Things;


std::hash_map


需要定义仿函数结构体

struct StringHashFunc  //hash 函数

{

size_t operator() (const string& str)const

        {

            return __stl_hash_string(str.c_str());

        };

};

struct StrCompare   //判断是否相等, 两个值hash统一位置,需要调用此函数判断主键是否存在

{

    bool operator()(const string& str, const string& str1) const

    {

        return strcmp(str.c_str(), str1.c_str())==0;

    }

};

typedef hash_set<string, StringHashFunc, StrCompare> T_StrEqueHashSet;


转载于:https://my.oschina.net/miffa/blog/213474

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值