搜索保存在文件中的哈希表

时间:2014-12-02 10:03:08

标签: c++ search hash

我编写了一个创建了哈希表并将其保存到文件中的程序。我应该编写第二个程序,允许用户输入密钥,在文件中搜索该密钥,并显示存储在与输入密钥匹配的记录中的信息。

我的程序已正确创建哈希表并将其保存到正确的文件中,但是,我在搜索文件时遇到问题。当我输入一个我知道在哈希表中的密钥时,我得到了我的"找不到这个密钥"信息。

这是我的代码:

我的标题文件:

//prog8.h
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

class Hash {
private:
    static const int hashSize = 8;
    struct record {
        int key;
        string name;
        int code;
        double cost;
        record* next;
    };
    record* hashTable[hashSize];
public:
    Hash();
    int hash(int key);
    void addRecord(int key, string name, int code, double cost);
    int numInIndex(int index);
    void saveRecords();
    void saveRecordsInIndex(int index);
    void findRecord(int key);
};

我的.cpp文件包含方法的定义:

//prog8.cpp
#include "prog8.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

Hash::Hash() {
    for(int i = 0; i < hashSize; i++) {
        hashTable[i] = new record;
        hashTable[i]->key = 8;
        hashTable[i]->name = "blank";
        hashTable[i]->code = 0;
        hashTable[i]->cost = 0.0;
        hashTable[i]->next = NULL;
    }
}
void Hash::addRecord(int key, string name, int code, double cost) {
    int index = hash(key);
    if(hashTable[index]->key == 8) {
        hashTable[index]->key = key;
        hashTable[index]->name = name;
        hashTable[index]->code = code;
        hashTable[index]->cost = cost;
    }
    else {
        record* ptr = hashTable[index];
        record* newRecord = new record;
        newRecord->key = key;
        newRecord->name = name;
        newRecord->code = code;
        newRecord->cost = cost;
        newRecord->next = NULL;
        while(ptr->next != NULL) {
            ptr = ptr->next;
        }
        ptr->next = newRecord;
    }
}
int Hash::numInIndex(int index) {
    int count = 0;
    if(hashTable[index]->key == 0) {
        return count;
    }
    else {
        count++;
        record* ptr = hashTable[index];
        while(ptr->next != NULL) {
            count++;
            ptr = ptr->next;
        }
    }
    return count;
}
int Hash::hash(int key) {
    int index = key % 5;
    return index;
}
void Hash::saveRecords() {
    ofstream recordsFile;
    recordsFile.open("records.dat");
    int number;
    for(int i = 0; i < hashSize; i++) {
        number = numInIndex(i);
        recordsFile << "-------------\n";
        recordsFile << "Index = " << i << endl;
        recordsFile << hashTable[i]->key << endl;
        recordsFile << hashTable[i]->name << endl;
        recordsFile << hashTable[i]->code << endl;
        recordsFile << hashTable[i]->cost << endl;
        recordsFile << "Number of items in index = " << number << endl;
        recordsFile << "-------------\n";
    }
}
void Hash::saveRecordsInIndex(int index) {
    ofstream recordsFile;
    recordsFile.open("records.dat");    
    record* ptr = hashTable[index];
    if(ptr->key == 0) {
        cout << "Index " << index << " is empty";
    }
    else {
        cout << "Index " << index << " contains the following records:\n";
        while(ptr != NULL) {
            recordsFile << "--------------\n";
            recordsFile << ptr->key << endl;
            recordsFile << "--------------\n";
            ptr = ptr->next;
            //index++;
        }
    }
}
void Hash::findRecord(int key) {
    ifstream recordsFile;
    recordsFile.open("records.dat");
    if(!recordsFile.is_open()) {
        cerr << "Error opening file" << endl;
    }
    int index = hash(key);
    bool wasFound = false;
    record* ptr = hashTable[index];
    while(ptr != NULL) {
        if(ptr->key == key) {
            wasFound = true;
            key = ptr->key;
        }
        ptr = ptr->next;
    }
    if(wasFound == true) {
        cout << key;
    }
    else {
        cout << "There was no record matching the key " << key << " found."
        << endl;
    }
    recordsFile.close();
}

我的第一个主要文件:

//prog8main.cpp
#include "prog8.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
    ifstream file;
    file.open("prog8.dat");
    if(!file.is_open()) {
        cerr << "Error opening file" << endl;
    }
    int index;
    int key;
    string name;
    int code;
    double cost;
    Hash hashObj;
    if(key != 8) {
        while(file >> key && file >> name && file >> code && file >> cost) {
            hashObj.addRecord(key, name, code, cost);
            hashObj.saveRecords();
            //hashObj.saveRecordsInIndex(index);
        }
    }
    file.close();
    return 0;
}

我的主文件搜索输出文件:

//prog8search.cpp
#include "prog8.h"
#include <iostream>
#include <fstream>
#include <string>
using namespace std;

int main() {
    int key;
    Hash hashObj;
    cout << "Please enter a key ";
    cin >> key;
    hashObj.Hash::findRecord(key);

    return 0;
}

以下是我获得的输出示例,其中包含已创建的records.dat文件:

[cs331129@cs ~]$ g++ -o prog8 prog8.cpp prog8main.cpp
[cs331129@cs ~]$ prog8
[cs331129@cs ~]$ cat records.dat
-------------
Index = 0
12345
Item06
45
14.2
Number of items in index = 2
-------------
-------------
Index = 1
34186
Item25
18
17.75
Number of items in index = 2
-------------
-------------
Index = 2
12382
Item09
62
41.37
Number of items in index = 3
-------------
-------------
Index = 3
8
blank
0
0
Number of items in index = 1
-------------
-------------
Index = 4
12434
Item04
21
17.3
Number of items in index = 1
-------------
-------------
Index = 5
8
blank
0
0
Number of items in index = 1
-------------
-------------
Index = 6
8
blank
0
0
Number of items in index = 1
-------------
-------------
Index = 7
8
blank
0
0
Number of items in index = 1
-------------
[cs331129@cs ~]$ g++ -o prog8search prog8.cpp prog8search.cpp
[cs331129@cs ~]$ prog8search
Please enter a key 12345
There was no record matching the key 12345 found.

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

我发现您的代码存在许多问题:

  1. 您的哈希索引大小是8?那你为什么要修改5?这意味着单元格5,6和7将始终为空,因为它们将被重定向到0,1和2.

  2. 为什么在main()中输出每个记录后输出?为什么不在最后这样做呢? (如果你没有坚持这种糟糕的支撑风格,你会更清楚自己在做什么,虽然其他人会在风格问题上不同意我的看法。)

  3. 您的代码当然是泄漏的,不是常规的,并且通常可以通过更好的结构来实现。

  4. &#34; findRecord&#34;做输入文件?我无法看到它。

  5. 你为什么要对key == 0进行检查?这不是一个有效的密钥吗?

答案 1 :(得分:1)

ifstream recordsFile;
recordsFile.open("records.dat");
if(!recordsFile.is_open()) {
    cerr << "Error opening file" << endl;
}

在这里你打开了文件。

但你什么都不读

所以,当你做像

这样的事情时
record* ptr = hashTable[index];

根据定义,该表将为空,因为您仍需要从records.dat文件中读取任何内容。

记住:编程不是魔术。起初看起来似乎是这样,但除非代码是由任何人编写的,否则什么都不会发生,