Fast HashTable

· · Tech. & Eng.

Fast HashTable 2.4

Update:

简介:

哈希表,常识了吧。

但是我的哈希表要快很多。

而且不会被 CF 之类的卡。

功能/使用:

版本:

效率比较:

时间:

空间:

综上,此上两种哈希表严格强于所有 STL/PB_DS 自带的容器。

实现:

template <typename Key, typename Value, const unsigned int Maxn> class HashTable { // Key, Value 跟 map 一样,Maxn 表示多少个数
private:
    unsigned int head[Maxn<<1], sz, limit;
    struct Edge { unsigned int next; Key key; Value val; } edge[Maxn];
    inline unsigned int hash(const string &s) {
        unsigned int hs = 0;
        for(unsigned int i=0; i<(unsigned int)s.size(); i++)    hs = (hs+s[i])*26;
        return hs&limit;
    }
    inline unsigned int hash(const char &ch) { return ch&limit; }
    template <typename T> inline unsigned int hash(const T &x) { return x&limit; }
public:
    inline HashTable() {
        limit = 1;
        for(int x=Maxn-1; x; x>>=1, limit<<=1);
        limit--;
    }
    Value& operator [] (Key x) {
        unsigned int hs = hash(x);
        for(unsigned int i=head[hs]; i; i=edge[i].next) {
            if(edge[i].key == x)    return edge[i].val;
        }
        edge[++sz] = {head[hs], x, Value()};
        return head[hs] = sz, edge[sz].val;
    }
    inline bool count(Key x) {
        unsigned int hs = hash(x);
        for(unsigned int i=head[hs]; i; i=edge[i].next) {
            if(edge[i].key == x)    return true;
        }
        return false;
    }
    inline Value get(Key x) {
        unsigned int hs = hash(x);
        for(unsigned int i=head[hs]; i; i=edge[i].next) {
            if(edge[i].key == x)    return edge[i].val;
        }
        return Value();
    }
    inline void clear() {
        memset(head, 0, (limit+1)<<2), sz = 0;
    }
};
template <typename Key, typename Value, const unsigned int Maxn> class HashTable {
 // Key, Value 跟 map 一样,Maxn 表示多少个数
private:
    Key key[Maxn<<1]; Value value[Maxn<<1]; int limit;
    inline unsigned int hash(const string &s) {
        unsigned int hs = 0;
        for(unsigned int i=0; i<(unsigned int)s.size(); i++)    hs = (hs+s[i])*26;
        return hs&limit;
    }
    inline unsigned int hash(const char &ch) { return ch&limit; }
    template <typename T> inline unsigned int hash(const T &x) { return x&limit; }
public:
    inline HashTable() {
        limit = 1;
        for(int x=Maxn-1; x; x>>=1, limit<<=1);
        limit--;
    }
    Value& operator [] (Key x) {
        unsigned int hs = hash(x);
        while(key[hs]!=x and value[hs]!=0)  hs = (hs+1)&limit;
        return key[hs] = x, value[hs];
    }
    inline bool count(Key x) {
        unsigned int hs = hash(x);
        while(key[hs]!=x and value[hs]!=0)  hs = (hs+1)&limit;
        return (key[hs] == x);
    }
    inline Value get(Key x) {
        unsigned int hs = hash(x);
        while(key[hs]!=x and value[hs]!=0)  hs = (hs+1)&limit;
        return value[hs];
    }
    inline void clear() {
        memset(key, 0, (limit+1)*sizeof(key[0]));
        memset(value, 0, (limit+1)*sizeof(value[0]));
    }
};

使用案例:防止某些人看不懂

#include<iostream>
#define ll long long
using namespace std;

// 复制一遍就好了,这里以拉链法为例,两种是一样的
template <typename Key, typename Value, const unsigned int Maxn> class HashTable { // Key, Value 跟 map 一样,Maxn 表示多少个数
private:
    unsigned int head[Maxn<<1], sz, limit;
    struct Edge { unsigned int next; Key key; Value val; } edge[Maxn];
    inline unsigned int hash(const string &s) {
        unsigned int hs = 0;
        for(unsigned int i=0; i<(unsigned int)s.size(); i++)    hs = (hs+s[i])*26;
        return hs&limit;
    }
    inline unsigned int hash(const char &ch) { return ch&limit; }
    template <typename T> inline unsigned int hash(const T &x) { return x&limit; }
public:
    inline HashTable() {
        limit = 1;
        for(int x=Maxn-1; x; x>>=1, limit<<=1);
        limit--;
    }
    Value& operator [] (Key x) {
        unsigned int hs = hash(x);
        for(unsigned int i=head[hs]; i; i=edge[i].next) {
            if(edge[i].key == x)    return edge[i].val;
        }
        edge[++sz] = {head[hs], x, Value()};
        return head[hs] = sz, edge[sz].val;
    }
    inline bool count(Key x) {
        unsigned int hs = hash(x);
        for(unsigned int i=head[hs]; i; i=edge[i].next) {
            if(edge[i].key == x)    return true;
        }
        return false;
    }
};

HashTable<ll, int, 100000> hs; // 定义

int main() {
    hs[x] += 5; // 修改 hx[x]
    cout<< hs[x]; // 调用 hs[x]
    if(hs.count(x)) // 查询 x 是否出现
    return 0;
}

结语:

随手写的,希望能帮到大家。

若有问题/bug,欢迎找我。

都看到这里了,点个赞在走吧。