-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
033a097
commit 0c38d15
Showing
21 changed files
with
1,915 additions
and
0 deletions.
There are no files selected for viewing
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
#include<iostream> | ||
#include<fstream> | ||
#include"HashTable.h" | ||
HashTable::HashTable ( ){} | ||
//you should really just return a bool over here it would be so much better | ||
void HashTable::RetrieveItem(Student& item, bool& found){ | ||
found = false; | ||
int hash = item.Hash(); | ||
for(int i = 0; i < MAX_ITEMS; ++i){ | ||
if(info[(hash+i)%MAX_ITEMS] == item){ | ||
item = info[(hash+i)%MAX_ITEMS]; | ||
found = true; | ||
break; | ||
} | ||
} | ||
|
||
} | ||
ERROR_CODE HashTable::InsertItem ( Student item ){ | ||
int i = 0; | ||
int hash = item.Hash(); | ||
while(info[(hash+i)%MAX_ITEMS].getID() != -1){ | ||
if(++i == MAX_ITEMS){return OVERFLOW;} | ||
} | ||
info[(hash+i)%MAX_ITEMS] = item; | ||
return SUCCESS; | ||
|
||
|
||
|
||
} | ||
ERROR_CODE HashTable::DeleteItem ( Student item ){ | ||
int hash = item.Hash(); | ||
for(int i = 0; i < MAX_ITEMS; ++i){ | ||
if(info[(hash+i)%MAX_ITEMS] == item){ | ||
info[(hash+i)%MAX_ITEMS].remove(); | ||
break; | ||
} | ||
} | ||
} | ||
void HashTable::print(){ | ||
for(Student s : info){ | ||
if(s.getID() != -1){ | ||
std::cout << s << std::endl; | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
//One of the questions asks for us to print the student given their ID | ||
//This is trivial to do with just the ID when the hash table is global | ||
//Of course, in general, global variables are to be avoided | ||
//So I made this non-member function that takes the table as a second argument | ||
//And returns the student with their details all updated (if the ID exists in the table) | ||
//If the ID is not found it just returns a student with ID = -1 | ||
//I still cannot fathom why Dr. Ghassan is so fond of "found" | ||
|
||
Student getStudent(int ID, HashTable table, bool& found){ | ||
Student s(ID, "", ""); | ||
table.RetrieveItem(s, found); | ||
if(found){return s;} | ||
else{ | ||
Student p; | ||
return p; | ||
} | ||
} | ||
|
||
|
||
int main(){ | ||
HashTable table; | ||
int ID; | ||
string fname; | ||
string lname; | ||
|
||
std::ifstream fin("student.txt"); | ||
if(fin.fail()){std::cerr << "Error opening student file!"; exit(1);} | ||
|
||
while(fin >> ID >> fname >> lname){ | ||
Student s(ID, fname, lname); | ||
if(table.InsertItem(s) == OVERFLOW){std::cout << "Could not insert student with ID" << ID << std::endl; break;} | ||
} | ||
|
||
fin.close(); | ||
|
||
std::cout << "Students before deleting a person" << std::endl; | ||
table.print(); | ||
|
||
bool found = false; | ||
Student s; | ||
while(!found){ | ||
std::cout << "Enter student ID to retrieve and delete" << std::endl; | ||
std::cin >> ID; | ||
s = getStudent(ID, table, found); | ||
} | ||
std::cout << "The student who you are removing/graduating is:" << std::endl; | ||
//making custom print functions is dumb when you can just do operator overloading | ||
std::cout << s << std::endl; | ||
table.DeleteItem(s); | ||
std::cout << "Students after you murdered/expelled that poor dude" << std::endl; | ||
table.print(); | ||
|
||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#ifndef HashTable_H | ||
#define HashTable_H | ||
#include "Student.cpp" | ||
|
||
//I hate ERROR_CODE and it sucks | ||
enum ERROR_CODE{OVERFLOW, UNDERFLOW, SUCCESS}; | ||
|
||
class HashTable | ||
{ | ||
public : | ||
HashTable ( ); | ||
void RetrieveItem(Student& item, bool& found); | ||
ERROR_CODE InsertItem ( Student item ); | ||
ERROR_CODE DeleteItem ( Student item ); | ||
void print(); | ||
private : | ||
|
||
Student info[MAX_ITEMS] ; | ||
}; | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
#include<iostream> | ||
#include<fstream> | ||
#include "Student.cpp" | ||
#include "UnsortedType.cpp" | ||
#define ListType UnsortedType | ||
|
||
enum ERROR_CODE{OVERFLOW, UNDERFLOW, SUCCESS}; | ||
|
||
//Again with this madness. Why can't you just call it a list? | ||
//Where on God's holy earth did you find a programmer who says "ListType" | ||
|
||
class hashtable | ||
{ | ||
public : | ||
hashtable ( ); | ||
void RetrieveItem(Student& item, bool& found); | ||
ERROR_CODE InsertItem ( Student item ); | ||
ERROR_CODE DeleteItem ( Student item ); | ||
void print(); | ||
private : | ||
|
||
ListType info[MAX_ITEMS] ; | ||
}; | ||
|
||
hashtable::hashtable ( ){} | ||
|
||
void hashtable::RetrieveItem(Student& item, bool& found){ | ||
found = false; | ||
int hash = item.Hash(); | ||
for(int i = 0; i < MAX_ITEMS; ++i){ | ||
if(info[(hash+i)%MAX_ITEMS] == item){ | ||
item = info[(hash+i)%MAX_ITEMS]; | ||
found = true; | ||
break; | ||
} | ||
} | ||
|
||
} | ||
ERROR_CODE hashtable::InsertItem ( Student item ){ | ||
int i = 0; | ||
int hash = item.Hash(); | ||
while(info[(hash+i)%MAX_ITEMS]->getID() != -1){ | ||
if(++i == MAX_ITEMS){return OVERFLOW;} | ||
} | ||
info[(hash+i)%MAX_ITEMS] = item; | ||
return SUCCESS; | ||
|
||
|
||
|
||
} | ||
ERROR_CODE hashtable::DeleteItem ( Student item ){ | ||
int hash = item.Hash(); | ||
for(int i = 0; i < MAX_ITEMS; ++i){ | ||
if(info[(hash+i)%MAX_ITEMS] == item){ | ||
info[(hash+i)%MAX_ITEMS]->remove(); | ||
break; | ||
} | ||
} | ||
} | ||
void hashtable::print(){ | ||
for(Student s : info){ | ||
if(s->getID() != -1){ | ||
std::cout << s << std::endl; | ||
} | ||
} | ||
} | ||
|
||
|
||
|
||
//One of the questions asks for us to print the student given their ID | ||
//This is trivial to do with just the ID when the hash table is global | ||
//Of course, in general, global variables are to be avoided | ||
//So I made this non-member function that takes the table as a second argument | ||
//And returns the student with their details all updated (if the ID exists in the table) | ||
//If the ID is not found it just returns a student with ID = -1 | ||
//I still cannot fathom why Dr. Ghassan is so fond of "found" | ||
|
||
Student getStudent(int ID, hashtable table, bool& found){ | ||
Student s(ID, "", ""); | ||
table.RetrieveItem(s, found); | ||
if(found){return s;} | ||
else{ | ||
Student p; | ||
return p; | ||
} | ||
} | ||
|
||
|
||
int main(){ | ||
hashtable table; | ||
int ID; | ||
string fname; | ||
string lname; | ||
|
||
std::ifstream fin("student.txt"); | ||
if(fin.fail()){std::cerr << "Error opening student file!"; exit(1);} | ||
|
||
while(fin >> ID >> fname >> lname){ | ||
Student s(ID, fname, lname); | ||
if(table.InsertItem(s) == OVERFLOW){std::cout << "Could not insert student with ID" << ID << std::endl; break;} | ||
} | ||
|
||
fin.close(); | ||
|
||
std::cout << "Students before deleting a person" << std::endl; | ||
table.print(); | ||
|
||
bool found = false; | ||
Student s; | ||
while(!found){ | ||
std::cout << "Enter student ID to retrieve and delete" << std::endl; | ||
std::cin >> ID; | ||
s = getStudent(ID, table, found); | ||
} | ||
std::cout << "The student who you are removing/graduating is:" << std::endl; | ||
//making custom print functions is dumb when you can just do operator overloading | ||
std::cout << s << std::endl; | ||
table.DeleteItem(s); | ||
std::cout << "Students after you murdered/expelled that poor dude" << std::endl; | ||
table.print(); | ||
|
||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
|
||
#include<string> | ||
using std::string; | ||
const int MAX_ITEMS= 101; | ||
class Student | ||
{ | ||
private: | ||
int studentID;//student id | ||
string firstName; | ||
string lastName; | ||
public: | ||
|
||
|
||
//provide constructors | ||
//provide getters and setters | ||
//provide overloaded opeartors <, > == based on student id. | ||
//provide print function to print student id and student record | ||
//number | ||
|
||
Student(){studentID = -1;} | ||
Student(int i, string f, string l): studentID(i), firstName(f), lastName(l){} | ||
|
||
//deliberately chosen so there is at least one collision | ||
int Hash(){return studentID%MAX_ITEMS;} | ||
|
||
int getID() const{return studentID;} | ||
string getFirst() const {return firstName;} | ||
string getLast() const {return lastName;} | ||
|
||
|
||
//copy constructor | ||
Student(const Student & s): Student(s.studentID, s.firstName, s.lastName){} | ||
~Student(){} | ||
|
||
Student&operator=(const Student& s){ | ||
if(this != &s){ | ||
studentID = s.studentID; | ||
firstName = s.firstName; | ||
lastName = s.lastName; | ||
} | ||
return *this; | ||
|
||
} | ||
|
||
/* | ||
I'm going to assume the ID of a student never changes once assigned, and therefore there's no need to provide a mutator. | ||
Why? Consider the case where hash(old_ID) = a, and hash(new_ID) = b, where a !=b. | ||
Moving student from info[a] to info[b] would remove a lot of the elegance of our solution | ||
*/ | ||
|
||
void remove(){studentID = -1;} | ||
void setFirst(string f){firstName = f;} | ||
void setLast(string l){lastName = l;} | ||
|
||
inline friend bool operator<(const Student& s1, const Student& s2){return s1.getID() < s2.getID();} | ||
inline friend bool operator>(const Student& s1, const Student& s2){return s2 < s1;} | ||
inline friend bool operator==(const Student& s1, const Student& s2){return s1.getID() == s2.getID();}; | ||
|
||
friend std::ostream& operator<<(std::ostream& cout, const Student& s){cout << s.getID() << " " << s.getFirst() << " " << s.getLast();return cout;}; | ||
|
||
|
||
}; | ||
|
||
|
||
|
Oops, something went wrong.