2014-12-02 3 views
1

해시 테이블을 생성하고 파일에 저장 한 프로그램을 작성했습니다. 나는 사용자가 키를 입력하고, 그 키에 대한 파일을 검색하고, 입력 된 키와 일치하는 레코드에 저장된 정보를 표시 할 수있는 두 번째 프로그램을 작성해야한다.파일에 저장된 해시 테이블 검색

내 프로그램에서 해시 테이블을 올바르게 만들고 올바른 파일에 저장했지만 파일을 검색하는 데 문제가 있습니다. 해시 테이블에있는 키를 입력하면 "이 키를 찾을 수 없습니다"라는 메시지가 나타납니다.

내 헤더 파일 :

//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; 
} 

An 여기

//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 파일로 완성 : :

[[email protected] ~]$ g++ -o prog8 prog8.cpp prog8main.cpp 
[[email protected] ~]$ prog8 
[[email protected] ~]$ 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 
------------- 
[[email protected] ~]$ g++ -o prog8search prog8.cpp prog8search.cpp 
[[email protected] ~]$ prog8search 
Please enter a key 12345 
There was no record matching the key 12345 found. 

어떤 도움이 라 내 주요 파일은 출력 파일을 검색 할 수 대단히 감사하겠습니다.

+0

저장소 선택에서 상당히 간결한 것으로 시작하십시오. 당신은 틀림없이 무의미한 양의 데이터를 당신에게 * 아무것도 쓰지 않지만 파일을 더 읽기 어렵게 만드는 .dat 파일에 저장합니다. – WhozCraig

+0

좋아,하지만 지금은 이미 내가 가지고있는 것을 어떻게 검색 할 수 있는지에 대한 아이디어가 있습니까? – HiTechRedneck3

+0

'findRecord'는 파일을 열지 만 아무것도 읽지 않으므로 테이블이 비어 있습니다. 아마도 "records.dat"를 기계가 읽을 수있는 형식으로 작성하고 싶을 것입니다. 또한 파일을 검색 할 때마다 파일을 읽는 것은 매우 비효율적입니다. 다른 기능에서 로딩 및 검색을 분리하십시오. – molbdnilo

답변

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

여기에서 파일을 열었습니다.

아직 아무 것도 읽지 않았습니다.. 당신이

record* ptr = hashTable[index]; 

같은 물건을 할 때 여전히 records.dat 파일에서 아무것도 읽을 필요하기 때문에

그래서 표는 정의에 의해 비어 있습니다.

기억 : 프로그래밍은 마법이 아닙니다. 처음에는 그렇게 보일 수 있지만, 코드를 작성하지 않는 한 아무것도 이제까지 (반드시 당신에게, 모든 사람에 의해)

+0

올바르게 읽으려면 어떻게해야하는지 잘 모르십니까? 기본적으로 입력 파일을 만들어 테이블을 만들었던 것처럼 해봤지만 키를 입력하라는 메시지가 나타나면 아무 것도 표시하지 않고 프로그램을 종료합니다. – HiTechRedneck3

+0

그게 입력 유효성 검사를하지 않는 증상입니다. 여기 시작 : ** [Live On Coliru] (http://coliru.stacked-crooked.com/a/38b286548e0ae376) ** 나는 이것이 해쉬 테이블이 될 수있는 방법을 명확하게 이해하지 못했다. 어떤 장소에서 해시로 키를 사용하고있을 수도 있지만 그건 당신에게 달려 있습니다.) – sehe

2

발생하지 난 당신의 코드와 함께 문제의 번호를 참조하십시오

  1. 귀하 해시 인덱스 크기가 8입니까? 너 왜 5 시까 지 개조하니? 즉, 셀 5, 6 및 7은 0, 1 및 2로 리디렉션 될 때 항상 비어 있습니다.

  2. 모든 레코드를 읽은 후 main()에서 출력하는 이유는 무엇입니까? 왜 그렇게하지 않습니까? (만약 당신이 그 끔직한 브레이싱 스타일을 주장하지 않았다면, 당신이하고있는 일이 더 분명해질 것입니다. 다른 사람들은 스타일 문제에 관해 나와 의견이 다를 것입니다.)

  3. 물론 코드가 누수되고 const-correct가 아니며 더 나은 구조화로 일반적으로 수행 할 수 있습니다.

  4. "findRecord"는 입력 파일과 무엇을합니까? 나는 그것을 읽는 것을 볼 수 없다.

  5. 왜 키 == 0인지 확인하고 계십니까? 그게 유효한 열쇠가 아닌가요?

+0

키 모드 5의 값인 지침의 일부로 제공된 해시 함수를 사용해야했습니다. 나는 이것을 빨아 들여 다음 학기에 효과적인 전공을 바꿀 이유가 있습니다. 내 마음은 이런 방식으로 작동하지 않습니다. 하루 종일이 모든 것들을 읽을 수 있습니다. 단지 클릭하지 않습니다. 그래서 저는 두 번째와 세 번째 문제에 대한 답변을 얻지 못했습니다. – HiTechRedneck3

+0

업계에서 일하는 저를 좋아하는 사람들은 교수님보다 좋은 코드를 작성하는 것에 대해 많은 것을 알고 있습니다. 당신은 세포 5, 6, 7이 항상 존재할 때 비어 있다는 것에 놀랐습니다. 0과의 비교는 다음과 같습니다. nt Hash :: numInIndex (int index) { int count = 0; if (hashTable [index] -> key == 0) { return count; – CashCow

+0

오, 의심 할 여지없이, 나는 너희 모두를 위해 최대한의 존경심을 가지고있다. 아니요. 보통 테이블 크기가 아닌 5로 수정 될 것이라는 사실을 깨달았을 때 그 사실을 깨닫지 못했습니다. 마지막 몇 공간을 사용하지 않을 것입니다. 나는 그가 우리가 처리해야 할 충돌을 우리가 얻을 수 있도록 보장하고 싶었던 것 같아요. 그리고 그것은 오타였습니다. 그것은 8보다는 오히려 0이었습니다. 우리는 파일에 "더미 레코드"를 채우겠다고했습니다. 파일의 첫 번째 숫자는 8 이었으므로, 그 위치는 . – HiTechRedneck3