Hashing(with chains) a student database (bit foldi

2019-08-29 03:13发布

问题:

I'm trying to hash a students database based on their ID (all their information is read through a text file). The hash-function I must use is the modulo of the sum of the ASCII code of each character in the ID, divided by an odd number representing the number of the hash 'buckets'.

For example, if the students ID is AE797989 and m=11:

Hash(AE797989)= [ASCII(‘A’)+ ASCII(‘E’)+ ASCII(‘7’)+ ASCII(‘9’)+ ASCII(‘7’)+ ASCII(‘9’)+ ASCII(‘8’)+ ASCII(‘9’)] mod m.

My text file consists of 19 students and looks something like this:

AE797989 Smith John 19.00 UE354567 Walsh Audrey 12.00 ... (it contains their ID number, surname, first name and grade)

In my main, I have an option where the user can choose to fill the database with the students in my text file. In that case, I call my function(located outside of my main): void insertToHash , where I open my file, and try to create a bucket for each student by calling a function I exclusively made for the hashing; called int* Hash.

I found a code for the hash-function I mentioned written in Java but since Strings are conceived differently in C, I get warnings when I compile. The code I found:

    int h(String x, int M) {
   char ch[];
   ch = x.toCharArray();
   int xlength = x.length();

   int i, sum;
   for (sum=0, i=0; i < x.length(); i++)
     sum += ch[i];
   return sum % M;
 }

And here are the functions I mentioned:

struct hash *hashTable = NULL;

struct node 
{
float grade;
char AM[100];
char first_name[100];
char last_name[100];
struct node *next;
}node;

struct hash 
{
struct node *head;
int count;
};

struct node * createNode(char *AM, char *first_name, char *last_name, float grade) 
{
struct node *newnode;

newnode = (struct node *) malloc(sizeof(struct node));
strcpy(newnode->AM, AM);
newnode->grade = grade;
strcpy(newnode->first_name, first_name);
strcpy(newnode->last_name, last_name);
newnode->next = NULL;
return newnode;
}

int* Hash(char **AM, int n)
{    
int i;
char* hashNum=0;

  for (i=0; i< 8; i++)
  {
  char *am = AM[i];
  hashNum += am;
  }

  int hashIndex = atoi(hashNum);
  return hashIndex % n;
}

void insertToHash(char *AM, char *first_name, char *last_name, float grade) 
{
FILE *fp;
fp = fopen ("Foitites-Vathmologio-DS.txt","rb");
if (fp == NULL) 
                { 
                fprintf(stderr,"Could not open file");  
                return;
                } 

while(fscanf(fp,"%s %s %s %d",node.AM, node.first_name, node.last_name, &node.grade) != EOF)
{   
int hashIndex = Hash(*AM, 19);

struct node *newnode = createNode(AM, first_name, last_name, grade);
/* head of list for the bucket with index "hashIndex" */

if (!hashTable[hashIndex].head) 
{
hashTable[hashIndex].head = newnode;
hashTable[hashIndex].count = 1;
return;
}

/* adding new node to the list */
newnode->next = (hashTable[hashIndex].head);
/*
* update the head of the list and no of
* nodes in the current bucket
*/
hashTable[hashIndex].head = newnode;
hashTable[hashIndex].count++;}
fclose(fp);
return;
}

For my function Hash(char **AM, int n) I get the warning: passing argument 1 of 'Hash' makes pointer from integer without a cast (I actually get that warning a lot and I've tried to fix it but keep making it worse)

For my line: hashNum += am; I get the error: invalid operands to binary (+ have 'char *' and 'char *')

I'm lost and would really appreciate the help, thanks!

回答1:

Well, your types are wrong.

Here

int* Hash(char **AM, int n) 

you tell that the function is to return a pointer to an integer. However, the function returns an integer.

Further, you tell that the function expects a pointer to a pointer to a char (and an int). However when you call it like

int hashIndex = Hash(*AM, 19); 

you pass a char (and an int).

I would expect your function to be more like:

int Hash(char *AM, int n)
{    
  int i;
  int hashIndex = 0;

  for (i=0; i< 8; i++)
  {
    hashIndex += AM[i];
  }

  return hashIndex % n;
}

and be called like:

int hashIndex = Hash(AM, 19); 


标签: c indexing hash