
Patrick B. answered 06/17/21
Math and computer tutor/teacher
I got some source code for you but it's too big to list here..
either shoot me an email or we upload to the cloud...
Here is my suggestion for the hash table:
1st you need the data structure:
typedef struct _TStudentRec
{
int studentNum;
float studentGPA;
} * TStudentRec;
then you build the methods for the linked list
struct _TStudentListNode
{
struct _TStudentRec studentRec;
struct _TStudentListNode * next;
) * TStudentListNode;
Typedef struct _TStudentList
{
TStudentListNode first;
TStudentListNode next;
int count;
} * TStudentList;
StudentList_init();
StudentList_push();
StudentList_ToArray();
StudentList_FromArray();
typedef struct _TStudentHash
{
struct _TStudentList [4]; // one for each department : CSE, ESE, ARC, etc
} * TStudentHash
finally:
struct _TStudentHash[15]; // one for each year: 2008,2009,...2021,2022
Array is indexed by subtracting 2008 from the year. For example, student graduating
in 2014 shall be at index 2014-2008=6, which is the 7th hash table
You then index by the department: 0=CSE, 1=ESE, 2=ARC,etc.
You may use the following code fragments to parse the buffer containing the student record:
char * trim(char *str)
{
char *end;
// Trims leading space
while(isspace((unsigned char)*str)) str++;
if(*str == 0) // All spaces?
return str;
// Trims trailing space
end = str + strlen(str) - 1;
while(end > str && isspace((unsigned char)*end)) end--;
// Writes new null terminator character
end[1] = '\0';
return str;
}
//converts GPA from format XXX to X.XX; ex. "345" --> 3.45
float GPA_unpack(char * strGPA3, char * strGPA4)
{
strGPA4[0] = strGPA3[0];
strGPA4[1] = '.';
strGPA4[2] = strGPA3[1];
strGPA4[3] = strGPA3[2];
strGPA4[4] = 0;
return(atof(strGPA4));
}
//converts GPA to 3 bytes; ex 3.45 --> "345"
void GPA_pack( float gpa, char * strGPA3)
{
char strGPA4[4];
memset(strGPA4,0,4);
sprintf(strGPA4,"%0.2f",gpa);
strGPA3[0] = strGPA4[0];
strGPA3[1] = strGPA4[2];
strGPA3[2] = strGPA4[3];
}
ParseStudentRec(TStudentRec studentRec, char * inbuff)
{
char dataBuff[5];
char * studentRecBuff = trim(inbuff);
char studentID[STUDENT_ID_LENGTH];
float gpa;
memset(studentID,0,STUDENT_ID_LENGTH);
//parses student id
strcpy(studentID,trim(strtok(studentRecBuff,"/")));
//graduation year
memset(dataBuff,0,5);
memcpy(dataBuff,studentID,4);
studentRec->year = (char) (atoi(dataBuff)-BASE_YEAR);
//department
memset(dataBuff,0,5);
memcpy(dataBuff,studentID+4,3);
if (strncmp(dataBuff,"CSE",3)==0)
{
studentRec->dept = DEPARTMENT_CSE;
}
else if (strncmp(dataBuff,"MEC",3)==0)
{
studentRec->dept = DEPARTMENT_MEC;
}
else if (strncmp(dataBuff,"ECE",3)==0)
{
studentRec->dept = DEPARTMENT_ECE;
}
else if (strncmp(dataBuff,"ARC",3)==0)
{
studentRec->dept=DEPARTMENT_ARC;
}
else
{
studentRec->dept = DEPARTMENT_NONE;
}
//student #
memset(dataBuff,0,5);
memcpy(dataBuff,studentID+7,4);
studentRec->studentNum= atoi(dataBuff);
//GPA
gpa = atof(strtok(NULL,"/"));
GPA_pack(gpa,studentRec->GPA);
}
DumpStudentRec(TStudentRec studentRec)
{
char GPA[5];
printf(" year = %d \n",studentRec->year+BASE_YEAR);
printf(" dept = %c \n",studentRec->dept);
printf(" student # = %d \n",studentRec->studentNum);
GPA[0] = studentRec->GPA[0];
GPA[1] = '.';
GPA[2] = studentRec->GPA[1];
GPA[3] = studentRec->GPA[2];
GPA[4] = 0;
printf(" GPA = %s \n",GPA);
}
GetStudentRecGPA(TStudentRec studentRec,TStudentGPA studentGPA)
{
char gpaBuff[5];
studentGPA->studentGPA = GPA_unpack(studentRec->GPA,gpaBuff);
studentGPA->studentNum = studentRec->studentNum;
}
int CompareByGPA(const void * rec1, const void * rec2)
{
TStudentGPA studentRecPtr1 = (TStudentGPA)rec1;
TStudentGPA studentRecPtr2 = (TStudentGPA)rec2;
int iReturn=0;
if (studentRecPtr1->studentGPA != studentRecPtr2->studentGPA)
{
iReturn = (studentRecPtr1->studentGPA > studentRecPtr2->studentGPA) ? 1 : -1;
}
return(iReturn);
}
int CompareByNum(const void * rec1, const void * rec2)
{
TStudentGPA studentRecPtr1 = (TStudentGPA)rec1;
TStudentGPA studentRecPtr2 = (TStudentGPA)rec2;
return(studentRecPtr1->studentNum - studentRecPtr2->studentNum);
}
StudentList_Init(TStudentList studentList)
{
studentList->first = studentList->last = NULL;
studentList->count=0;
}
StudentList_Push(TStudentList studentList, TStudentGPA studentRecGPA)
{
TStudentListNode newStudentListNode = (TStudentListNode)malloc(STUDENT_LIST_NODE_SIZE);
memcpy(&newStudentListNode->studentGPA,studentRecGPA,STUDENT_GPA_SIZE);
newStudentListNode->next = NULL;
if (studentList->count==0)
{
studentList->first = studentList->last = newStudentListNode;
}
else
{
studentList->last->next = newStudentListNode;
studentList->last = studentList->last->next;
}
studentList->count++;
}
//transfers student records from list to array; list is destroyed
StudentList_ToArray(TStudentList studentList, TStudentGPA arrayStudentGPA, int * n)
{
int iLoop;
TStudentListNode cur= studentList->first;
*n = studentList->count;
for (iLoop=0; iLoop<studentList->count; iLoop++)
{
studentList->first = studentList->first->next;
memcpy(&arrayStudentGPA[iLoop],&cur->studentGPA,STUDENT_GPA_SIZE);
free(cur);
cur = studentList->first;
}
studentList->count=0;
studentList->first = studentList->last=NULL;
}
//transfers student records from array to list; array is destroyed
StudentList_FromArray(TStudentList studentList, TStudentGPA arrayStudentGPA, int * n)
{
int count = *n;
int iLoop;
StudentList_Init(studentList);
for (iLoop=0; iLoop<count; iLoop++)
{
StudentList_Push(studentList,&arrayStudentGPA[iLoop]);
}
free(arrayStudentGPA);
arrayStudentGPA=NULL;
}