【发布时间】:2020-09-03 14:15:18
【问题描述】:
所以我正在尝试为我的 C++ 课程编写一个项目,在该项目中我读取了一个 .txt 文件,其中包含 53 行城市、州和多余的信息。
(例如:Port Jervis,NY,New York,36071,Orange,36071,41.3782,-74.6909,16410.0,1317)
读取文件后,我将城市名称(例如:Port Jervis)和州代码(例如:NY)分开,并使用州代码中两个字母的值作为 13 个元素的哈希表的键.所以 N=13 + Y=24 = key of 37,因为哈希有 13 个元素,所以 37 % 13 = hash-key of 11。
到目前为止一切顺利,我能够正确完成所有工作,但是在显示结果时我遇到了一个问题,因为哈希表的每个元素都缺少一个链接链表。所以它只显示 53 个中的 40 个输出,每个元素缺少 1 个,我真的不知道为什么。
所以我通过电子邮件向教授发送了我的代码,他说我的插入方法不正确,他认为这是导致此错误的原因。我当前的插入方法看起来像
void insert(int key, string city, string state)//insert value
{
int hash = KeyModFunction(key); //function that's %13 for hash-key
Node* tmpInsert = new Node(key, city, state); //create node to work with
if(table[hash]==NULL)//checks if table is empty
{
table[hash] = tmpInsert; //if empty, make new node with key/city/state values
}
else//if not empty
{
Node *runner = table[hash]; //made node to run through the list
while(runner->next != NULL)//make it to the end
{
runner=runner->next; // go go go
}
runner->next = tmpInsert; //and point the end at the new node to be inserted
}
} //end insert
我的教授建议它应该看起来更像
if(table[hash]->next == NULL)
{
table[hash]->next = tmpInsert;
table[hash]->myCity = city;
table[hash]->myState = state;
}
else
{
// You can figure out the else code based on the above
但是,每当我将它放入我的代码中时,它就不再编译并说存在段错误。但是当我通过调试器运行它时,它说“[Inferior 1 (process 5453) exited normal]”我不会撒谎,我不确定这是什么意思,也无法在线找到具体的答案.但是我假设正常退出是一件好事,但是没有显示任何内容。
我整个星期都在为此苦苦挣扎,试图找出解决方案,最终到了我知道自己对此太过分了的地步,所以我来到这里希望找到一些指导,建议,或者至少有人为我指明正确的方向。如果这里需要我的更多代码,请告诉我,我只是不想把我的整个项目都扔在这里,因为我有理由想弄清楚,而不是让别人为我做,但是是的,我米卡住了。提前感谢您的帮助!
****2:12PST - 2020 年 5 月 17 日更新****
所以平心而论,插入代码是从其他人的代码中提取和修改的,我在网上找到了如何做到这一点,所以这可能就是为什么它看起来比我的教授更好(我也很确定他提到C++ 不是他最熟悉的语言)。是的,我们应该自己实现哈希表。
这是完整的程序:
class Node{
public:
int key;
string myCity;
string myState;
Node *next;
Node(int key, string myCity, string myState)//constructor
{
this->key = key;
this->myCity = myCity;
this->myState = myState;
this->next = NULL;
}
};//end Node
class Hash{
private:
int BUCKET; //number of over all values
Node** table;
public:
//Constructor
Hash(int V)
{
this->BUCKET = V; //setting the BUCKET size to max number of enteries
table = new Node*[BUCKET]; //create table with size of BUCKET
for(int i = 0; i < BUCKET; i++) //fill table with NULL values
{
table[i] = NULL;
}
} //end constructor
//KeyModFunction
int KeyModFunction(int x) //getting the hash key value
{
return (x % BUCKET);
} //end KeyModFunction
//Insert Function
void insert(int key, string city, string state)//insert value
{
int hash = KeyModFunction(key); //function that's %13 for hash-key
Node* tmpInsert = new Node(key, city, state); //create node to work with
if(table[hash]==NULL)//checks if table is empty
{
table[hash] = tmpInsert; //if empty, make new node with key/city/state values
}
else//if not empty
{
Node *runner = table[hash]; //made node to run through the list
while(runner->next != NULL)//make it to the end
{
runner=runner->next; // go go go
}
runner->next = tmpInsert; //and point the end at the new node to be inserted
}
} //end insert
//Display function
void displayHash()
{
for(int loop = 0; loop < BUCKET; loop++)
{
cout<<loop;
if(table[loop]->next != NULL)
{
Node* tmp;
tmp = table[loop]->next;
do
{
cout<<" -->"<<tmp->myCity<<"/"<<tmp->myState;
tmp = tmp->next;
}while(tmp!=NULL);
}
cout<<endl;
}
}//end displayHash
}; //end Hash Class
int main() {
cout << "CSP 31B - Read and Process Assignment\n\n";
char myAlpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; //the key array for all the letter values
Hash myTbl(13); //create hashmap with BUCKET size of 13
string fCity, fState, fExtra; //string variables to hold info
int key = 0; //hash value of the state code (two letters added together)
ifstream myfile("CityOut.txt");
while ( getline(myfile, fCity, ',') && getline(myfile, fState, ','))
{
getline(myfile, fExtra);
for(int i = 0; i < sizeof(myAlpha)/sizeof(myAlpha[0]); i++)
{
if(fState.at(0) == myAlpha[i])
{
key += i;
}
else if(fState.at(1) == myAlpha[i])
{
key += i;
}
}
int checkNum = 1;
cout << "DEBUGGER: City name: "<<fCity <<" State code: " << fState.at(0) << fState.at(1) <<" key = "<<key<<endl; //temporary statement for debugging purposes
myTbl.insert(key, fCity, fState);
key = 0; //reset hash number to zero for next line of CityOut.txt
}
cout<<endl<<endl<<endl;
myTbl.displayHash();
return 0;
}//end main
但每个表格元素应该多出 1 个输出
【问题讨论】:
-
打印结果的函数是什么样的?
-
你必须自己实现哈希表,还是只使用
std::unordered_map?如果您必须自己实现它,您可能只需看看std::unordered_map的界面就可以学到很多东西,这几乎满足了您的教授的建议。 -
坦率地说,你的代码看起来比教授的要好(这对我来说毫无意义)。
-
另请注意,您的
if-else是多余的。while循环足以找到您的(大概)单链表的末尾。但是,根据您发布的信息,我认为没有人能够找到您的错误。 -
我同意 Buddy 的观点,该错误可能与插入代码一样容易出现在打印代码中。由于您使用的是调试器,这告诉您插入函数的工作原理是什么?什么时候多余的元素会丢失?