This commit is contained in:
Samuel Oberhofer 2022-06-18 14:51:31 +02:00
parent 4d480a5c62
commit 70cdab95d1
6 changed files with 293 additions and 0 deletions

View File

@ -0,0 +1,51 @@
# Name of the binary for Development
BINARY = main
# Name of the binary for Release
FINAL = prototyp
# Object files
OBJS = Ware.o hashTable.o main.o
# Compiler flags
CFLAGS = -Werror -Wall -std=c++17 -fsanitize=address,undefined -g
# Linker flags
LFLAGS = -fsanitize=address,undefined
#Which Compiler to use
COMPILER = c++
# all target: builds all important targets
all: binary
final : ${OBJS}
${COMPILER} ${LFLAGS} -o ${FINAL} ${OBJS}
binary : ${OBJS}
${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS}
# Links the binary
${BINARY} : ${OBJS}
${COMPILER} ${LFLAGS} -o ${BINARY} ${OBJS}
# Compiles a source-file (any file with file extension .c) into an object-file
#
# "%" is a wildcard which matches every file-name (similar to * in regular expressions)
# Such a rule is called a pattern rule (because it matches a pattern, see https://www.gnu.org/software/make/manual/html_node/Pattern-Rules.html),
# which are a form of so called implicit rules (see https://www.gnu.org/software/make/manual/html_node/Implicit-Rules.html)
# "$@" and "$<" are so called automatic variables (see https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html)
%.o : %.cpp
${COMPILER} -c ${CFLAGS} -o $@ $<
# Rules can not only be used for compiling a program but also for executing a program
run: ${BINARY}
./${BINARY}
# Delete all build artifacts
clean :
rm -rf ${BINARY} ${OBJS}
# all and clean are a "phony" targets, meaning they are no files
.PHONY : all clean

View File

@ -0,0 +1,9 @@
#include "Ware.h"
std::ostream &operator<<(std::ostream &out, const Ware &ware) {
out << "Name: " << ware.getBezeichnung() << ", SN: " << ware.getSeriennummer()
<< ", Gewicht: " << ware.getGewicht()
<< ", EK: " << ware.getEinkaufspreis()
<< ", VK: " << ware.getVerkaufspreis();
return out;
}

46
Uebung 4/Uebung4_1/Ware.h Normal file
View File

@ -0,0 +1,46 @@
#pragma once
#include <iostream>
#include <string>
class Ware {
private:
std::string bezeichnung;
int seriennummer;
double gewicht;
double einkaufspreis;
double verkaufspreis;
public:
std::string getBezeichnung() const { return this->bezeichnung; }
void setBezeichnung(std::string bezeichnung) {
this->bezeichnung = bezeichnung;
}
int getSeriennummer() const { return this->seriennummer; }
void setSeriennummer(int seriennummer) { this->seriennummer = seriennummer; }
double getGewicht() const { return this->gewicht; }
void setGewicht(double gewicht) { this->gewicht = gewicht; }
double getEinkaufspreis() const { return this->einkaufspreis; }
void setEinkaufspreis(double einkaufspreis) {
this->einkaufspreis = einkaufspreis;
}
double getVerkaufspreis() const { return this->verkaufspreis; }
void setVerkaufspreis(double verkaufspreis) {
this->verkaufspreis = verkaufspreis;
}
Ware(std::string bezeichnung, int seriennummer, double gewicht,
double einkaufspreis, double verkaufspreis)
: bezeichnung(bezeichnung), seriennummer(seriennummer), gewicht(gewicht),
einkaufspreis(einkaufspreis), verkaufspreis(verkaufspreis) {}
};
std::ostream &operator<<(std::ostream &out, const Ware &ware);

View File

@ -0,0 +1,89 @@
#include "hashTable.h"
#include <iostream>
HashTable::HashTable() {
this->size = 0;
this->entries = nullptr;
this->setHashFunction("firstTwoLetters");
}
HashTable::HashFunction::HashFunction(std::string name,
hashFunctionPtr algorithm, int size) {
this->name = name;
this->algorithm = algorithm;
this->size = size;
}
void HashTable::insert(Ware *entry) {
int hashValue = this->hashFunction(entry->getBezeichnung());
hashValue = hashValue % this->size;
HashNode node;
node.key = entry->getBezeichnung();
node.ware = entry;
this->entries[hashValue].push_back(node);
}
void HashTable::print() {
std::cout << "=====================================" << std::endl;
for (int i = 0; i < this->size; i++) {
std::cout << i << " :\t";
for (auto it = this->entries[i].begin(); it != this->entries[i].end();
it++) {
if (it != this->entries[i].begin()) {
std::cout << "\t|\t";
}
std::cout << it->key;
}
std::cout << std::endl;
}
std::cout << "=====================================" << std::endl;
}
void HashTable::setHashFunction(std::string algorithmName) {
for (int i = 0; i < 5; i++) {
if (this->availableAlgorithms[i].name == algorithmName) {
this->hashFunction = this->availableAlgorithms[i].algorithm;
this->size = this->availableAlgorithms[i].size;
if (this->entries != nullptr) {
delete[] this->entries;
}
this->entries = new std::list<HashNode>[this->size];
return;
}
}
std::cerr << "The Hash Function provided was not found!" << std::endl;
}
const Ware *HashTable::search(std::string key) {
int hashValue = this->hashFunction(
key); // key is "hashed" and stored in the variable int hashValue
hashValue = hashValue % this->size;
for (auto it = this->entries[hashValue].begin();
it != this->entries[hashValue].end(); it++) {
if (it->key == key) {
return it->ware;
}
}
std::cout << "Ware with bezeichnung " << key << " not found!" << std::endl;
return nullptr;
}
bool HashTable::deleteItem(std::string key) {
int hashValue = this->hashFunction(key);
hashValue = hashValue % this->size;
for (auto it = this->entries[hashValue].begin();
it != this->entries[hashValue].end(); it++) {
if (it->key == key) {
delete it->ware;
it = this->entries[hashValue].erase(it);
return true;
}
}
return false;
}
int firstTwoLetters(std::string bezeichnung) {
return (int)(bezeichnung[0] + bezeichnung[1]);
}

View File

@ -0,0 +1,54 @@
#include "Ware.h"
#include <list>
#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 mod17(std::string telNr); // hash algorithm that takes a given telNr mod17
int firstTwoLetters(std::string bezeichnung);
class HashTable {
private:
class HashFunction { // private inner class to make hash functions managable
public:
int size;
std::string name;
hashFunctionPtr algorithm;
HashFunction(std::string name, hashFunctionPtr algorithm,
int size); // constructor
};
HashFunction availableAlgorithms[1] = {
{"firstTwoLetters", firstTwoLetters, 100}};
class HashNode { // private inner class for HashNodes that have a key (which
// will be the telephone number) and a value of type Ware
public:
std::string key = "";
Ware *ware;
};
public:
int size; // m in lecture
int numberOfEntries; // n in lecture
std::list<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
void insert(Ware *entry);
const Ware *search(std::string key);
bool deleteItem(std::string key);
void print();
void setHashFunction(std::string name);
HashTable(); // default constructor
int getHash(std::string bezeichnung) const;
};

View File

@ -0,0 +1,44 @@
#include "Ware.h"
#include "hashTable.h"
#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[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
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() {
HashTable ht;
// Insert 100 random Wares
for (int i = 0; i < 100; i++) {
ht.insert(new Ware(random_string(5), 123, 2.0, 2.0, 2.0));
}
// Insert 2 additional ones with known Names
ht.insert(new Ware("Testware", 123, 2.0, 2.0, 2.0));
ht.insert(new Ware("Foo", 123, 2.0, 2.0, 2.0));
ht.print();
// Search for one that should exist and print it.
const Ware *s1 = ht.search("Testware");
std::cout << *s1 << std::endl;
// Delete the Ware we found
bool test = ht.deleteItem("Testware");
std::cout << test << std::endl;
// Try to delete a Ware which does not exist.
bool test2 = ht.deleteItem("Bar");
std::cout << test2 << std::endl;
}