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