哈希表实现《C++实践之路》

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40364485/article/details/82686181

首先,弄一个字符缓冲器来存取这些key

const int maxBufSize = 500;   //设置缓冲器最大值
class StringBuffer{   
public:
    StringBuffer():_curOffset(0){}    
    bool WillFit(int len) const {return _curOffset + len + 1 < maxBufSize;}               //判断加进新的key后缓冲器会不会爆满
    void Add(char const *str){       //把key粘到缓冲器后面
        strcpy(&_buf[_curOffset], str);
        _curOffset += strlen(str) + 1;    //offset这时当然是得改的啦
    }
    int GetOffset() const{return _curOffset;}
    bool IsEqual(int offStr, char const *str) const{  //在缓冲器里面找key,其实也就是哈希查找啦
        char const *strStored = &_buf[offStr];
        return strcmp(str, strStored) == 0;
    }
    char const *GetString(int offStr) const{return &_buf[offStr];}
private:
    char _buf[maxBufSize];    //缓冲器
    int _curOffset;      //给出当前的offset,就是从这里之前的是用过的,之后的就是待用的
};

然后弄哈希表

const int sizeHTable = 127;     //哈希表最大值
class HTable{
public:
    list <int> const &Find(char const *str) const ;   //应该都知道哈希表在冲突的时候会把这些冲突的玩意儿弄成一个链表然后查找时再在链表里遍历吧
    void Add(char const *str, int id);     //添加新的键值对到哈希表里
private:
    int hash(char const *str) const;    //哈希函数,根据这个函数来算一个id以此构成键值对
    list <int>_aList[sizeHTable];  //这个链表是存取那些id的,也就是值
};

其中各函数的实现就给个课本的哈希函数吧,其他自行实现

int HTable::hash(char const *str)const{
    assert(str != 0 && str[0] != 0);   
    unsigned h = str[0];   
    for(int i = 1; str[i] != 0; i++){
        h = (h << 4) + str[i];    //这个式子为什么这么奇葩呢,课本上说这个式子应该要结合实际情况考虑,以减小冲突为原则,然后弄出一个值来做id
    }
    return h % sizeHTable;
}

最后是字符串表

class StringTable{
public:
    StringTable();
    int ForceAdd(char const *str);    //听名字就挺6了,强制添加,管你key会不会重复,我就是要加
    int Find(char const *str) const;   //查找
    char const *GetString(int id) const;    //根据id反侦察出key
private:
    HTable _htab;    //一个哈希表
    int _offStr[maxStrings];   //一个关于offset的数组,给缓冲器用的,数组元素是id,也就是用_offStr[id]指出id对应的字符串你要在缓冲器的哪里可以找到
    int _curId;    //当前指向的东东的id
    StringBuffer _strBuf;    //缓冲器
};

函数实现,就挑一个坑了我的Find()函数来讲

int StringTable::Find(char const *str) const{
    list<int> const &l = _htab.Find(str);
                                 //用迭代器对list进行遍历
    for(list<int>::const_iterator i = l.begin(); i != l.end(); i++){ 
        int t_id = *i;
        int offStr = _offStr[t_id];
        if(_strBuf.IsEqual(offStr, str))
            return t_id;
    }
    return idNotFound;
}

乡亲们,就是这个const_iterator,我当时直接把i的类型定义为listiterator,搞了挺久才发现因为l是const类型,它的begin也得是const_iterator,关于迭代器还是有的学的。
其它没实现的函数都是随便写


就酱

展开阅读全文

没有更多推荐了,返回首页