【问题标题】:Resizing and copying elements in a Hashtable Array调整和复制哈希表数组中的元素
【发布时间】:2020-06-08 17:23:58
【问题描述】:

现在我有一个结构IndexLocation,它在页面上定义一个页码pageNum和一个字号wordNum,还有一个结构IndexRecord,它由一个特定的字和它的locations组成IndexLocations 的向量。

在 IndexRecord.h 中:

struct IndexLocation {
    int pageNum; //1 = first page
    int wordNum; //1 = first word on page

    IndexLocation(int pageNumber, int wordNumber);
};

struct IndexRecord {
    //indexed word
    std::string word;
    //list of locations it appears
    std::vector<IndexLocation> locations;

    IndexRecord();

    //Constructor - make a new index record with no locations
    explicit IndexRecord(const std::string& wordVal);

    //Add an IndexLocation to the record
    // Does NOT check for duplicate records
    void addLocation(const IndexLocation& loc);

    //Returns true if the record contains the indicated location
    bool hasLocation(const IndexLocation& loc) const;
};

然后,我有一个哈希映射IndexMap,它使用word 作为键存储IndexRecords 的值。在一个内,IndexRecord 可以存储在bucket 3,有一个word 苹果,locations 是 1,2 和 2,5。

#include "IndexRecord.h"
class IndexMap
{
private:
    int numBuckets;
    int keyCount;
    IndexRecord* buckets;

    //handle resizing the hash table into a new array with twice as many buckets
    void grow();

    //Get the location this key should be placed at.
    //  Will either containt IndexRecord with that key or an empty IndexRecord
    unsigned int getLocationFor(const std::string& key) const;

public:
    //Construct HashMap with given number of buckets
    IndexMap(int startingBuckets = 10);

    //Destructor
    ~IndexMap();

    //Copy constructor and assignment operators
    IndexMap(const IndexMap &other);
    IndexMap& operator=(const IndexMap& other);

    //Returns true of indicated key is in the map
    bool contains(const std::string& key) const;

    //Add indicated location to the map.
    //  If the key does not exist in the map, add an IndexRecord for it
    //  If the key does exist, add a Location to its IndexRecord
    void add(const std::string& key, int pageNumber, int wordNumber);

    void IndexMap::add2(const std::string &key, IndexLocation location)
};

此外,在 IndexMap.cpp 中,我有 add 函数、add2 函数和 grow 函数。

void IndexMap::add(const std::string &key, int pageNumber, int wordNumber) {
    if (keyCount == numBuckets)
        grow();

    int bucketNumber = getLocationFor(key);

    if (this->contains(key) == true)
        buckets[bucketNumber].addLocation(IndexLocation(pageNumber, wordNumber));
    else if (this->contains(key) == false) {
        while (buckets[bucketNumber].word != "?") {
            if (bucketNumber < numBuckets)
                bucketNumber++;
            else if (bucketNumber == numBuckets)
                bucketNumber = 0;
        }

        string foo = key;
        buckets[bucketNumber].word = key;
        buckets[bucketNumber].addLocation(IndexLocation(pageNumber, wordNumber));
        keyCount++;
    }
    return;
}

void IndexMap::add2(const std::string &key, IndexLocation location) {
    if (keyCount > 0.7 * numBuckets)
        grow();

    int bucketNumber = getLocationFor(key);

    if (this->contains(key) == true)
        buckets[bucketNumber].addLocation(location);
    else if (this->contains(key) == false) {
        while (buckets[bucketNumber].word != "?") {
            if (bucketNumber < numBuckets)
                bucketNumber++;
            else if (bucketNumber == numBuckets)
                bucketNumber = 0;
        }

        string foo = key;
        buckets[bucketNumber].word = key;
        buckets[bucketNumber].addLocation(location);
        keyCount++;
    }
    return;
}

void IndexMap::grow() {
    IndexRecord* oldTable = buckets;
    int oldSize = numBuckets;
    numBuckets = numBuckets * 2 + 1;
    IndexRecord* newArray = new IndexRecord[numBuckets];
    keyCount = 0;
    for (int i = 0; i < oldSize; i++) {
        if (oldTable[i].word != "?") {
            this->add2(oldTable[i].word, oldTable[i].locations[i]); // having trouble here
        }
    }
    buckets = newArray;
    delete [] oldTable;
}

我的问题从这里开始。我相信我的基本逻辑是合理的:用指针保留旧数组,创建一个新的更大的数组并重置 HashTable 的大小,遍历旧数组并使用 add 函数将其中包含的任何内容添加回哈希表中,然后删除旧数组,但这只会在keyCount 命中numBuckets 时导致分段错误(SIGSEGV)。 (我有一个add2 函数几乎与我的add 函数相同并在grow 中使用它的原因是因为我不知道如何修改为@ 获取pageNumber 和wordNumber grow 内的 987654347@ 行;赋值规范说我们不能修改原始 add 函数的标题)。

【问题讨论】:

    标签: c++ hashmap


    【解决方案1】:

    您永远不会在grow 中分配给buckets,因此您的其他函数无法访问新扩大的数组。

    【讨论】:

    • 这么说,你的意思是最后有buckets = newArray;之类的东西吗?
    • @Logan87654321 您应该在分配给newArray 后立即拥有它,因为add2 需要访问新数组。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-12
    • 2021-08-01
    • 1970-01-01
    • 2016-05-19
    • 2013-11-01
    相关资源
    最近更新 更多