【发布时间】:2019-08-05 15:49:43
【问题描述】:
在尝试将节点添加到链表的前面时,无法弄清楚我的逻辑哪里出错了。该程序允许双输入和重复节点。现在看看逻辑一段时间,并继续似乎确定我哪里出错了。问题一定很简单,我在看它。似乎继续将其添加到相同的linked_list而不是每个用户不同的列表 导致 are 的输入是 山姆 P丽莎 P 标记 帕米 F丽莎艾米 菲丽莎马克 F艾米山姆
执行后问题就很清楚了
#include <iostream>
#include <string.h>
#include <stdio.h>
#include <cstring>
using namespace std;
void menu_function(void);
void command_execute( string command, string name1, string name2);
int hash_function(string str);
void insert_into_hashtable( int ascii_total, string name);
void add_friendship( int ascii_key, string name );
void print_friendships( int aascii_key);
void check_friendship( int ascii_key, string name);
void remove_friendship( int ascii_key, string name );
#define SIZE 150
struct friend_list
{
string name;
struct friend_list* next;
};
typedef struct friend_list list;
struct user{
string name;
int key;
friend_list* FriendList;
};
struct user* hashArray[SIZE];
int main(int argc, const char * argv[]) {
menu_function();
return 0;
}
void menu_function(){
char user_input[100];//this could limit the size of input
string command;
string name1 = "\0";
string name2 = "\0";;
char* token;
int inputsize = 100;
int i = 0;
char delimit[]=" \t\r\n\v\f";
while( 1 )
{
printf("\nP <Name> to create a person\n");
printf("F <Name> <Name> record friendship\n");
printf("U <Name> <Name> terminate friendship\n");
printf("L <Name> print out friends of a specified person\n");
printf("Q <Name> <Name> check friendship status of two people\n");
printf("X - terminate the progarm\n");
// Determine user input and
fgets(user_input, inputsize, stdin);
//getline(&input, &inputsize, stdin);//takes in user input;
//parsing e string for the data within
token = strtok( user_input, delimit);
i = 0;
while( token != NULL ){
if(i == 0)
{
command = token;
//cout<< command<<endl;
}
if(i == 1)
{
name1 = token;
// cout<< name1<<":"<<endl;
}
if( i == 2 )
{
name2 = token;
// cout<< name2<<":"<<endl;
name1 = name1 + "\n";
}
token = strtok( NULL, " " );
i++;
}
command_execute( command, name1, name2);
command = '\0';
name1 = '\0';
name2 = '\0';
}
}
void command_execute( string command, string name1, string name2)
{
//cout<<"command is: "<<command<<endl;
switch( command[0])
{
case 'P': //Create record of the person
insert_into_hashtable( hash_function(name1), name1);
break;
case 'F': //Record friendship
add_friendship(hash_function(name1), name2);
add_friendship(hash_function(name2), name1);
break;
case 'U': //Terminate Friendship
remove_friendship( hash_function(name1), name2);
remove_friendship( hash_function(name2), name1);
break;
case 'L': //Print out the persons Friends
print_friendships( hash_function(name1));
break;
case 'Q': //Check on friendship
check_friendship( hash_function(name1), name2);
break;
case 'X': //Exit the program **** COMPLETED
exit(1);
break;
default:
cout<<"Error occured based on your command please try again"<<endl;
break;
}
}
int hash_function(string string){
//going to use the ASCI value of the name with different weights per array position to hash the names
int ascii_key = 0;
int ascii_total = 0;
// cout<< string.length()<< endl;
//cout<< string<< endl;
for( int i = 0; i < string.length()-1; i++)
{
ascii_total = (int) string[i] * (i*3+1);
// cout<< string[i]<< endl;
}
ascii_key = ascii_total % SIZE;
//deals with colisions through open hashing
/*
while(hashArray[ascii_key] != NULL || hashArray[ascii_key]-> key != ascii_key) { //strcmp(hashArray[ascii_key]->name.c_str(), string.c_str())
//hashArray[ascii_key] != NULL ||
ascii_key++;
}
*/
// ****** decide size of the hash table and then finished hashing function. Usually hash time is gonna be half full
cout<< ascii_key<<endl;
return ascii_key;
}
void insert_into_hashtable( int ascii_key, string name)
{
//get the hash key
user *item = new user;
item->name= name;
item->key = ascii_key;
item->FriendList = NULL;
//cout<< ascii_key<<endl;
//store the user in the table
hashArray[ascii_key] = item;
delete(item);
}
void add_friendship( int ascii_key, string name )
{
//gonna have to check for valid input on users
list* add = new friend_list;
list** temp = &hashArray[ascii_key]->FriendList;
add->name = name;
add->next = NULL;
if( temp == NULL )
{
//cout<<hashArray[ascii_key]->FriendList<<endl;
*temp = add;
}
else
{
add->next = *temp;
*temp = add;
}
print_friendships(ascii_key);
}
void print_friendships( int ascii_key)
{
friend_list* temp = hashArray[ascii_key]->FriendList;
while( temp != NULL )
{
cout<<temp->name<<endl;
if( temp->next == NULL)
{
return;
}
temp = temp->next;
}
}
【问题讨论】:
-
我很确定我不需要阅读所有这些
printf语句来理解您的链表问题,而且我绝对确定我不会尝试。请发布minimal complete and verifiable example,而不是仅仅粘贴整个程序。 -
那个编辑有帮助吗?
-
建议:考虑将列表、哈希表和好友逻辑分离到各自的类中。现在你已经把你的方式耦合到了不必要的高复杂性中,为了调试程序的一个方面,你必须调试所有三个方面。这违反了封装和低耦合,这是面向对象编程的两个关键原则。
-
不相关:如果您添加一个额外的间接层,将
list* temp = hashArray[ascii_key]->FriendList;更改为list** temp = &hashArray[ascii_key]->FriendList;,您可以不必再次查找hashArray[ascii_key]。add->next = hashArray[ascii_key]->FriendList;变为add->next = *temp;和hashArray[ascii_key]->FriendList = add;变为*temp = add; -
我没有在给定的代码中看到您报告的错误。你删除的太多了。提供minimal reproducible example 时,不要忘记完成。 MCVE 的真正目标是让您将代码破解为一个更简单的程序,即 bug、整个 bug,除了 bug 什么都没有。您几乎不必一路走到真正的 MCVE,因为随着所涉及的代码量减少,该错误隐藏的空间越来越小,您可以自己找到并修复它。这就是分离职责派上用场的地方:删除不需要的东西以便正确调查问题更容易。
标签: c++ linked-list hashtable