【发布时间】: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 函数的标题)。
【问题讨论】: