【问题标题】:C++ Hash Table and Linked List IssuesC++ 哈希表和链表问题
【发布时间】: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 的观点,该错误可能与插入代码一样容易出现在打印代码中。由于您使用的是调试器,这告诉您插入函数的工作原理是什么?什么时候多余的元素会丢失?

标签: c++ insert hashmap


【解决方案1】:

您的打印代码会跳过哈希表的第一个元素。

这段代码:

        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<<loop;
        if(table[loop] != NULL)
        {
          Node* tmp;
          tmp = table[loop];
          do
          {
            cout<<" -->"<<tmp->myCity<<"/"<<tmp->myState;
            tmp = tmp->next;
          }while(tmp!=NULL);
        }

【讨论】:

    猜你喜欢
    • 2016-12-01
    • 1970-01-01
    • 2023-03-13
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多