4.1
This commit is contained in:
parent
4d480a5c62
commit
70cdab95d1
|
|
@ -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
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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]);
|
||||||
|
}
|
||||||
|
|
@ -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;
|
||||||
|
};
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue