4.2
This commit is contained in:
parent
8737713cd9
commit
73b9c1a8af
|
|
@ -4,23 +4,26 @@
|
|||
HashTable::HashTable() {
|
||||
this->size = 0;
|
||||
this->entries = nullptr;
|
||||
this->setHashFunction("lastNumber");
|
||||
this->setHashFunction("mod17");
|
||||
this->numberOfEntries = 0;
|
||||
}
|
||||
|
||||
HashTable::HashFunction::HashFunction(std::string name, hashFunctionPtr algorithm, int size) {
|
||||
HashTable::HashFunction::HashFunction(std::string name,
|
||||
hashFunctionPtr algorithm, int size) {
|
||||
this->name = name;
|
||||
this->algorithm = algorithm;
|
||||
this->size = size;
|
||||
}
|
||||
|
||||
|
||||
void HashTable::insert(PbEntry *entry) {
|
||||
int hashValue = this->hashFunction(entry->telephoneNumber);
|
||||
hashValue = hashValue % this->size;
|
||||
|
||||
if(this->entries[hashValue].key == "" || this->entries[hashValue].key == "deleted") {
|
||||
if (this->entries[hashValue].key == "" ||
|
||||
this->entries[hashValue].key == "deleted") {
|
||||
this->entries[hashValue].key = entry->telephoneNumber;
|
||||
this->entries[hashValue].phonebookEntry = entry;
|
||||
this->numberOfEntries++;
|
||||
} else {
|
||||
bool inserted = false;
|
||||
int i = (hashValue + 1) % this->size;
|
||||
|
|
@ -32,31 +35,60 @@ void HashTable::insert(PbEntry* entry) {
|
|||
if (this->entries[i].key == "" || this->entries[i].key == "deleted") {
|
||||
this->entries[i].key = entry->telephoneNumber;
|
||||
this->entries[i].phonebookEntry = entry;
|
||||
this->numberOfEntries++;
|
||||
inserted = true;
|
||||
}
|
||||
i = (i + 1) % this->size;
|
||||
}
|
||||
}
|
||||
std::cout << "Number of current Entries: " << this->numberOfEntries
|
||||
<< ", LoadFactor: " << this->getloadFactor() << std::endl;
|
||||
if (this->getloadFactor() > 2.0 / 3.0) {
|
||||
if (this->size <= 17) {
|
||||
std::cout << "Upgrading to mod37" << std::endl;
|
||||
this->setHashFunction("mod37");
|
||||
} else if (this->size <= 37) {
|
||||
std::cout << "Upgrading to mod71!" << std::endl;
|
||||
this->setHashFunction("mod71");
|
||||
} else {
|
||||
std::cout << "Cannot upgrade further. Desastrous Failure imminent!!"
|
||||
<< std::endl;
|
||||
if (this->numberOfEntries == this->size) {
|
||||
std::cout
|
||||
<< "Could not insert. Hashtable is full and can not be expanded"
|
||||
<< std::endl;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void HashTable::print() {
|
||||
std::cout << "=====================================" << std::endl;
|
||||
for (int i = 0; i < this->size; i++) {
|
||||
std::cout << i << " :\t" << this->entries[i].key << std::endl;
|
||||
|
||||
}
|
||||
std::cout << "=====================================" << std::endl;
|
||||
}
|
||||
|
||||
void HashTable::setHashFunction(std::string algorithmName) {
|
||||
for(int i = 0; i < 4; i++) {
|
||||
for (int i = 0; i < 6; i++) {
|
||||
if (this->availableAlgorithms[i].name == algorithmName) {
|
||||
HashNode *oldEntries = this->entries;
|
||||
int oldsize = this->size;
|
||||
this->hashFunction = this->availableAlgorithms[i].algorithm;
|
||||
this->size = this->availableAlgorithms[i].size;
|
||||
if(this->entries != nullptr) {
|
||||
delete[] this->entries;
|
||||
}
|
||||
this->numberOfEntries = 0;
|
||||
this->entries = new HashNode[this->size];
|
||||
if (oldEntries != nullptr) {
|
||||
for (int i = 0; i < oldsize; i++) {
|
||||
if (oldEntries[i].phonebookEntry != nullptr) {
|
||||
|
||||
this->insert(oldEntries[i].phonebookEntry);
|
||||
}
|
||||
}
|
||||
delete[] oldEntries;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -65,10 +97,12 @@ void HashTable::setHashFunction(std::string algorithmName) {
|
|||
}
|
||||
|
||||
const PbEntry *HashTable::search(std::string key) {
|
||||
int hashValue = this->hashFunction(key); // key is "hashed" and stored in the variable int hashValue
|
||||
int hashValue = this->hashFunction(
|
||||
key); // key is "hashed" and stored in the variable int hashValue
|
||||
hashValue = hashValue % this->size;
|
||||
int i = 0;
|
||||
while(this->entries[hashValue].key != key && this->entries[hashValue].key != "" && i <= this->size) {
|
||||
while (this->entries[hashValue].key != key &&
|
||||
this->entries[hashValue].key != "" && i <= this->size) {
|
||||
hashValue = (hashValue + 1) % this->size;
|
||||
i++;
|
||||
}
|
||||
|
|
@ -76,7 +110,8 @@ const PbEntry* HashTable::search(std::string key) {
|
|||
if (this->entries[hashValue].key == key) {
|
||||
return this->entries[hashValue].phonebookEntry;
|
||||
} else {
|
||||
std::cout << "Entry with telephone number " << key << " not found!" << std::endl;
|
||||
std::cout << "Entry with telephone number " << key << " not found!"
|
||||
<< std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -85,7 +120,8 @@ bool HashTable::deleteItem(std::string key) {
|
|||
int hashValue = this->hashFunction(key);
|
||||
hashValue = hashValue % this->size;
|
||||
|
||||
while(this->entries[hashValue].key != key && this->entries[hashValue].key != "") {
|
||||
while (this->entries[hashValue].key != key &&
|
||||
this->entries[hashValue].key != "") {
|
||||
hashValue = (hashValue + 1) % this->size;
|
||||
}
|
||||
|
||||
|
|
@ -93,18 +129,23 @@ bool HashTable::deleteItem(std::string key) {
|
|||
this->entries[hashValue].key = "deleted";
|
||||
this->entries[hashValue].phonebookEntry = nullptr;
|
||||
delete this->entries[hashValue].phonebookEntry;
|
||||
this->numberOfEntries--;
|
||||
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
float HashTable::getloadFactor() {
|
||||
return (float)this->numberOfEntries / this->size;
|
||||
}
|
||||
|
||||
/* algorithm that "hashes" the last digit of a number */
|
||||
int lastNumber(std::string telNr) {
|
||||
if (telNr.length() <= 0) {
|
||||
std::cerr << "Number '" << telNr << "' does not contain enough digits. At least 1 needed!";
|
||||
std::cerr << "Number '" << telNr
|
||||
<< "' does not contain enough digits. At least 1 needed!";
|
||||
exit(1);
|
||||
}
|
||||
return std::stoi(std::string(telNr.end() - 1, telNr.end()));
|
||||
|
|
@ -113,7 +154,8 @@ int lastNumber(std::string telNr) {
|
|||
/* algorithm that "hashes" the first three digits of a number */
|
||||
int firstThreeNumbers(std::string telNr) {
|
||||
if (telNr.length() < 3) {
|
||||
std::cerr << "Number '" << telNr << "' does not contain enough digits. At least 3 needed!";
|
||||
std::cerr << "Number '" << telNr
|
||||
<< "' does not contain enough digits. At least 3 needed!";
|
||||
exit(1);
|
||||
}
|
||||
return std::stoi(std::string(telNr.begin(), telNr.begin() + 3));
|
||||
|
|
@ -122,14 +164,18 @@ int firstThreeNumbers(std::string telNr) {
|
|||
/* algorithm that "hashes" the last three digits of a number */
|
||||
int lastThreeNumbers(std::string telNr) {
|
||||
if (telNr.length() < 3) {
|
||||
std::cerr << "Number '" << telNr << "' does not contain enough digits. At least 3 needed!";
|
||||
std::cerr << "Number '" << telNr
|
||||
<< "' does not contain enough digits. At least 3 needed!";
|
||||
exit(1);
|
||||
}
|
||||
return std::stoi(std::string(telNr.end() - 3, telNr.end()));
|
||||
}
|
||||
|
||||
/* algorithm that "hashes" the through mod17 */
|
||||
int mod17(std::string telNr) {
|
||||
return (int)(std::stol(telNr)%17);
|
||||
}
|
||||
int mod17(std::string telNr) { return (int)(std::stol(telNr) % 17); }
|
||||
|
||||
/* algorithm that "hashes" the through mod37 */
|
||||
int mod37(std::string telNr) { return (int)(std::stol(telNr) % 37); }
|
||||
|
||||
/* algorithm that "hashes" the through mod71 */
|
||||
int mod71(std::string telNr) { return (int)(std::stol(telNr) % 71); }
|
||||
|
|
|
|||
|
|
@ -1,13 +1,23 @@
|
|||
#include <string>
|
||||
#include "pbEntry.h"
|
||||
#include <string>
|
||||
|
||||
#pragma once
|
||||
typedef int (*hashFunctionPtr)(std::string); // typedefinition of a pointer for a hashfunction; they all need conform to the guideline: int <functionName>(std::string <param>)
|
||||
int lastNumber(std::string telNr); // hash algorithm that uses only the last digit of a given telNr
|
||||
int firstThreeNumbers(std::string telNr); // hash algorithm that uses the first three digits of a given telNr
|
||||
int lastThreeNumbers(std::string telNr); // hash algorithm that uses the last three digits of a given telNr
|
||||
typedef int (*hashFunctionPtr)(
|
||||
std::string); // typedefinition of a pointer for a hashfunction; they all
|
||||
// need conform to the guideline: int
|
||||
// <functionName>(std::string <param>)
|
||||
int lastNumber(std::string telNr); // hash algorithm that uses only the last
|
||||
// digit of a given telNr
|
||||
int firstThreeNumbers(std::string telNr); // hash algorithm that uses the first
|
||||
// three digits of a given telNr
|
||||
int lastThreeNumbers(std::string telNr); // hash algorithm that uses the last
|
||||
// three digits of a given telNr
|
||||
int mod17(std::string telNr); // hash algorithm that takes a given telNr mod17
|
||||
|
||||
int mod37(std::string telNr); // hash algorithm that takes a given telNr mod37
|
||||
|
||||
int mod71(std::string telNr); // hash algorithm that takes a given telNr mod71
|
||||
|
||||
class HashTable {
|
||||
private:
|
||||
class HashFunction { // private inner class to make hash functions managable
|
||||
|
|
@ -16,29 +26,40 @@ class HashTable {
|
|||
std::string name;
|
||||
hashFunctionPtr algorithm;
|
||||
|
||||
HashFunction(std::string name, hashFunctionPtr algorithm, int size); // constructor
|
||||
HashFunction(std::string name, hashFunctionPtr algorithm,
|
||||
int size); // constructor
|
||||
};
|
||||
|
||||
HashFunction availableAlgorithms[4] = { {"lastNumber", lastNumber, 10}, {"firstThreeNumbers", firstThreeNumbers, 1000}, {"lastThreeNumbers", lastThreeNumbers, 1000}, {"mod17", mod17, 17}};
|
||||
HashFunction availableAlgorithms[6] = {
|
||||
{"lastNumber", lastNumber, 10},
|
||||
{"firstThreeNumbers", firstThreeNumbers, 1000},
|
||||
{"lastThreeNumbers", lastThreeNumbers, 1000},
|
||||
{"mod17", mod17, 17},
|
||||
{"mod37", mod37, 37},
|
||||
{"mod71", mod71, 71}};
|
||||
|
||||
class HashNode { // private inner class for HashNodes that have a key (which will be the telephone number) and a value of type PbEntry
|
||||
class HashNode { // private inner class for HashNodes that have a key (which
|
||||
// will be the telephone number) and a value of type PbEntry
|
||||
public:
|
||||
std::string key = "";
|
||||
PbEntry *phonebookEntry;
|
||||
HashNode() : key(""), phonebookEntry(nullptr) {}
|
||||
};
|
||||
|
||||
public:
|
||||
int size; // m in lecture
|
||||
int numberOfEntries; // n in lecture
|
||||
HashNode *entries; // nodes of the hash table
|
||||
hashFunctionPtr hashFunction; // pointer to the hash algorithm used is stored in a private variable of type hashFunctionPtr - see beginning of this file
|
||||
|
||||
hashFunctionPtr hashFunction; // pointer to the hash algorithm used is stored
|
||||
// in a private variable of type
|
||||
// hashFunctionPtr - see beginning of this file
|
||||
|
||||
void insert(PbEntry *entry);
|
||||
const PbEntry *search(std::string key);
|
||||
bool deleteItem(std::string key);
|
||||
void print();
|
||||
void setHashFunction(std::string name);
|
||||
float getloadFactor();
|
||||
|
||||
HashTable(); // default constructor
|
||||
};
|
||||
|
|
@ -1,7 +1,20 @@
|
|||
#include "hashTable.h"
|
||||
#include "pbEntry.h"
|
||||
#include <string>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
|
||||
// Function to generate random strings for our Wares. See:
|
||||
// https://stackoverflow.com/a/12468109
|
||||
std::string random_string(size_t length) {
|
||||
auto randchar = []() -> char {
|
||||
const char charset[] = "0123456789";
|
||||
const size_t max_index = (sizeof(charset) - 1);
|
||||
return charset[rand() % max_index];
|
||||
};
|
||||
std::string str(length, 0);
|
||||
std::generate_n(str.begin(), length, randchar);
|
||||
return str;
|
||||
}
|
||||
|
||||
int main() {
|
||||
PbEntry entry1("3277971", "Norma Noe", "North Lyme Drive 30");
|
||||
|
|
@ -15,7 +28,11 @@ int main() {
|
|||
ht.insert(&entry3);
|
||||
ht.insert(&entry4);
|
||||
ht.insert(&entry5);
|
||||
for (int i = 0; i < 60; i++) {
|
||||
ht.insert(new PbEntry(random_string(7), "test", "test"));
|
||||
}
|
||||
ht.print();
|
||||
std::cout << ht.getloadFactor() << std::endl;
|
||||
|
||||
// ht.setHashFunction("mod17");
|
||||
// ht.insert(&entry1);
|
||||
|
|
|
|||
Loading…
Reference in New Issue