【问题标题】:How to correctly implement hash insert function in c++?如何在 C++ 中正确实现哈希插入函数?
【发布时间】:2020-12-04 21:00:07
【问题描述】:

我需要读取一个文件,然后通过链表冲突处理将每个单词存储到哈希表中,并计算每个单词出现的次数(节点的值)。当我用小文本(如 30 行)运行我的代码时,它可以工作,但从大约 100 行开始它会崩溃(分段错误:11)。我知道我的hashCode 功能不好,但它不应该崩溃。我认为问题在于我如何增加价值。

using namespace std;

class HashNode
{
public:
    string key;
    string value;

public:
    HashNode(string key, int value)
    {
        this->key = key;
        this->value = value;
    }
    friend class HashTable;
};

class HashTable {
    private:
        list<HashNode> *buckets; 
        int size;               
        int capacity;           
        int collisions;

    public:
        HashTable(int capacity){
            buckets = new list<HashNode>[capacity];
            this->capacity = capacity;
            this->size = 0;
            this->collisions = 0;
        }
        ~HashTable()
        {
            for (int i = 0; i < capacity; i++)
                buckets[i].clear();

            delete[] this->buckets;
        }
        int hashCode(string key)
        {
            int sum = 0;
            for (int k = 0; k < key.length(); k++)
                sum = sum + int(key[k]);
            return sum % capacity;
        }
        void insert(string key)
        {
            int value=0;
            int index = hashCode(key) % this->capacity; 

            for (list<HashNode>::iterator it = buckets[index].begin(); it != buckets[index].end(); ++it)
                if (it->key == key)
                {
                    it->value+=1; 
                    return;
                }
            if (buckets[index].size() > 0)
                collisions++;

            buckets[index].push_back(HashNode(key, value)); 
            this->size++;                                   
        }

        int getCollisions()
        {
            return this->collisions;
        }

};

int main() {
    string user_input;
    string word;
    ifstream inFile;
    string parameter;
    string command;
    HashTable object(80000);
    inFile.open("file.txt");
    cout << "Welcome " << endl;
    if (!inFile)
    {
        cout << "Unable to open the file";
        exit(1); 
    }
    listOfCommand();
    while (inFile >> word)
    {   
        object.insert(word);
    }
}
    

什么会导致这个崩溃?任何帮助将不胜感激!

【问题讨论】:

  • 您是否尝试调试过您的代码?它将显示崩溃的地方。如果您需要帮助,请发帖minimal reproducible example。我看到的问题是使用原始指针来存储数组,为什么不使用vector
  • 你在哪里分配list&lt;HashNode&gt; *buckets;应该指向的列表?
  • 请发帖minimal reproducible example。我们无法知道您未显示的代码有什么问题。您发布的代码缺少必要的细节,如果它们也没有出现在您的真实代码中,那将解释很多,但是您的真实代码看起来如何我们无法知道
  • 如果您的代码有未定义的行为,那么“它适用于 30 行”也无济于事。似乎在某些条件下工作并在月球处于不同阶段时爆炸是 ub 的典型特征
  • 感谢我发布了我所有的代码

标签: c++ linked-list hashmap hash-function


【解决方案1】:

很可能 char 在您的系统中已签名,因此将其转换为 sum = sum + int(key[k]); 行中的整数会导致负值,然后在尝试使用负索引获取 buckets[index] 时出现分段错误。

修复它的一种快速方法是首先将key[k] 转换为无符号字符,然后再转换为int:

for (int k = 0; k < key.length(); k++) {
    unsigned char c = static_cast<unsigned_char>(key[k]);
    sum = sum + static_cast<int>(c);
}

【讨论】:

  • 似乎有点迂回。这是不允许为负数的索引,所以将sum(和indexsizecapacity)从int 更改为unsigned 并且不需要更有意义额外的演员表?
猜你喜欢
  • 2010-09-06
  • 1970-01-01
  • 2023-03-04
  • 2016-03-25
  • 2011-01-19
  • 2017-05-02
  • 2018-07-12
  • 2015-02-02
  • 2011-11-22
相关资源
最近更新 更多