Init
This commit is contained in:
21
P2/ADS_P2_2_Hashtable/CMakeLists.txt
Executable file
21
P2/ADS_P2_2_Hashtable/CMakeLists.txt
Executable file
@@ -0,0 +1,21 @@
|
||||
# Set the minimum required version of CMake
|
||||
cmake_minimum_required(VERSION 3.11)
|
||||
|
||||
# Set the project name and specify the C++ as the project language
|
||||
project(P2_2_Hashtable)
|
||||
|
||||
# Specify the C++ standard
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# set(SOURCE_DIR "ADS/ADS-Praktika/P1/")
|
||||
add_executable(P2_2_Hashtable main.cpp hashtable.cpp unit_tests.cpp)
|
||||
|
||||
# Include directories for the target
|
||||
# target_include_directories(Hashtable PRIVATE ${SOURCE_DIR})
|
||||
|
||||
# Find and link OpenMP
|
||||
find_package(OpenMP REQUIRED)
|
||||
if(OpenMP_CXX_FOUND)
|
||||
target_link_libraries(P2_2_Hashtable PRIVATE OpenMP::OpenMP_CXX)
|
||||
endif()
|
||||
18182
P2/ADS_P2_2_Hashtable/catch.h
Executable file
18182
P2/ADS_P2_2_Hashtable/catch.h
Executable file
File diff suppressed because it is too large
Load Diff
172
P2/ADS_P2_2_Hashtable/hashtable.cpp
Executable file
172
P2/ADS_P2_2_Hashtable/hashtable.cpp
Executable file
@@ -0,0 +1,172 @@
|
||||
#include "hashtable.h"
|
||||
#include <iostream>
|
||||
#include <cmath> // Für std::ceil
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
HashTable::HashTable(int size, double threshhold, int methode) {
|
||||
hashTable = new vector<int>(size, -1);
|
||||
this->size = size;
|
||||
this->threshhold_rehashing = threshhold;
|
||||
this->m_sondierMethode = methode;
|
||||
this->elements = 0;
|
||||
this->collisionCount = 0;
|
||||
}
|
||||
|
||||
HashTable::~HashTable() {
|
||||
this->size = 0;
|
||||
this->elements = 0;
|
||||
this->collisionCount = 0;
|
||||
this->hashTable->clear();
|
||||
delete hashTable;
|
||||
}
|
||||
|
||||
int get_next_prime(int x) {
|
||||
x = x + 1;
|
||||
bool found = true;
|
||||
while (true) {
|
||||
found = true;
|
||||
for (int i = 2; i <= sqrt(x); i++) {
|
||||
if (x % i == 0) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return x;
|
||||
}
|
||||
x += 1;
|
||||
}
|
||||
}
|
||||
|
||||
int get_last_prime(int x) {
|
||||
x = x - 1;
|
||||
bool found = true;
|
||||
while (true) {
|
||||
found = true;
|
||||
for (int i = 2; i <= sqrt(x); i++) {
|
||||
if (x % i == 0) {
|
||||
found = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
return x;
|
||||
}
|
||||
x -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Berechnung des Hashwertes
|
||||
int HashTable::hashValue(int item) {
|
||||
switch (m_sondierMethode) {
|
||||
case (1): {
|
||||
// Lineares Sondieren
|
||||
int i = 0;
|
||||
int index = (item + i) % getSize();
|
||||
|
||||
while (hashTable->at(index) != -1) {
|
||||
collisionCount++;
|
||||
i++;
|
||||
index = (item + i) % getSize();
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
case (2): {
|
||||
// Quadr. Sondieren
|
||||
int i = 0;
|
||||
int index = (item + (i * i)) % getSize();
|
||||
|
||||
while (hashTable->at(index) != -1) {
|
||||
collisionCount++;
|
||||
i++;
|
||||
index = (item + (i * i)) % getSize();
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
case (3): {
|
||||
// Doppeltes Hashing
|
||||
int R = get_last_prime(getSize());
|
||||
|
||||
int i = 0;
|
||||
int index = (item + i * (R - (item % R))) % getSize();
|
||||
|
||||
while (hashTable->at(index) != -1) {
|
||||
collisionCount++;
|
||||
i++;
|
||||
index = (item + i * (R - (item % R))) % getSize();
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
void HashTable::rehashing() {
|
||||
int newSize = get_next_prime(2 * getSize());
|
||||
if (newSize < 1000) {
|
||||
vector<int>* newTable = new vector<int>(newSize, -1);
|
||||
collisionCount = 0;
|
||||
|
||||
for (int i = 0; i < getSize(); i++) {
|
||||
if (hashTable->at(i) != -1) {
|
||||
int newIndex = hashTable->at(i) % newSize;
|
||||
int j = 0;
|
||||
while (newTable->at(newIndex) != -1) {
|
||||
j++;
|
||||
collisionCount++;
|
||||
|
||||
// Neue Hash Funktion für das Rehashing
|
||||
// h(k_i) = k_i mod neueGröße
|
||||
newIndex = (newIndex + j) % newSize;
|
||||
}
|
||||
newTable->at(newIndex) = hashTable->at(i);
|
||||
}
|
||||
}
|
||||
|
||||
hashTable = newTable;
|
||||
size = newSize;
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
}
|
||||
|
||||
int HashTable::insert(int item) {
|
||||
elements++;
|
||||
double resizeLimit = getSize() * threshhold_rehashing;
|
||||
|
||||
if (getElements() >= resizeLimit) {
|
||||
rehashing();
|
||||
}
|
||||
|
||||
int index = hashValue(item);
|
||||
hashTable->at(index) = item;
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
int HashTable::at(int i) {
|
||||
return hashTable->at(i);
|
||||
}
|
||||
|
||||
int HashTable::getCollisionCount() {
|
||||
return this->collisionCount;
|
||||
}
|
||||
|
||||
int HashTable::getSize() {
|
||||
return this->size;
|
||||
}
|
||||
|
||||
int HashTable::getElements() {
|
||||
return this->elements;
|
||||
}
|
||||
35
P2/ADS_P2_2_Hashtable/hashtable.h
Executable file
35
P2/ADS_P2_2_Hashtable/hashtable.h
Executable file
@@ -0,0 +1,35 @@
|
||||
#ifndef _HASHTABLE_H_
|
||||
#define _HASHTABLE_H_
|
||||
|
||||
#include <vector>
|
||||
#include <math.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
class HashTable {
|
||||
public:
|
||||
HashTable(int size, double threshold=0.6, int methode=2); // Konstruktor
|
||||
~HashTable(); // Destruktor
|
||||
int insert(int item); // fuegt ein Element der Hashtabelle hinzu
|
||||
int at(int i); // Liefert das i-te Element der Hashtabelle zurueck
|
||||
int getCollisionCount(); // Liefert die Anzahl der Kollisionen zurueck
|
||||
int getSize(); // Liefert die Groesse der Hashtabelle zurueck
|
||||
int getElements(); // Liefert die Anzahl der Elemente der Hashtabelle zurueck
|
||||
void print(); // Ausgabe der Hashtable ind er Form:
|
||||
// [0] -> 1
|
||||
// .....
|
||||
private:
|
||||
int size; // Groesse der HashTable
|
||||
int elements; // Anz. d. Elemente in HashTable
|
||||
int collisionCount; // Anz. d. Kollisionen beim Einfuegen
|
||||
double threshhold_rehashing; // Schwellwert fuers rehashing (size/elements)
|
||||
int m_sondierMethode; // Sondier Methode 1 - linear, 2 - quadratisch, 3 - doppeltes Hashing
|
||||
vector<int>* hashTable; // HashTable
|
||||
int hashValue(int item); // calculate hash value
|
||||
void rehashing(); // rehashing
|
||||
};
|
||||
|
||||
// Helper Funktion:
|
||||
int get_next_Prime(int a); // Gibt zu einer natuerlichen Zahl a, die naechstgroessere Primzahl zurueck
|
||||
int get_last_Prime(int a); // Gibt zu einer natuerlichen Zahl a, die naechstkleienre Primzahl zurueck
|
||||
#endif
|
||||
30
P2/ADS_P2_2_Hashtable/main.cpp
Executable file
30
P2/ADS_P2_2_Hashtable/main.cpp
Executable file
@@ -0,0 +1,30 @@
|
||||
#define CATCH_CONFIG_RUNNER
|
||||
#include "catch.h"
|
||||
#include <iostream>
|
||||
#include "hashtable.h"
|
||||
#include <cstdlib> // Für rand() und srand()
|
||||
#include <ctime> // Für time()
|
||||
|
||||
int main() {
|
||||
Catch::Session().run();
|
||||
|
||||
// Initialisiere den Zufallsgenerator
|
||||
srand(static_cast<unsigned int>(time(0)));
|
||||
|
||||
int option = 1;
|
||||
while (0 < option && option < 4) {
|
||||
std::cout << "Wählen Sie die Sondierungsmethode : \n1 - linear\n2 - quadratisch\n3 - Doppeltes Hashing\n> ";
|
||||
std::cin >> option;
|
||||
HashTable H(1000, 0.6, option);
|
||||
|
||||
for (int i = 0; i < 200; ++i) {
|
||||
int randomValue = 1000 + rand() % 501;
|
||||
H.insert(randomValue);
|
||||
}
|
||||
|
||||
std::cout << "Anzahl der Kollisionen: " << H.getCollisionCount() << std::endl;
|
||||
}
|
||||
|
||||
system("pause");
|
||||
return 0;
|
||||
}
|
||||
120
P2/ADS_P2_2_Hashtable/unit_tests.cpp
Executable file
120
P2/ADS_P2_2_Hashtable/unit_tests.cpp
Executable file
@@ -0,0 +1,120 @@
|
||||
/*************************************************
|
||||
* ADS Praktikum 2
|
||||
* Unit-Testdatei
|
||||
* Stand: 20.05.2024
|
||||
*
|
||||
*************************************************
|
||||
* Änderungen untersagt!
|
||||
*************************************************/
|
||||
#include <vector>
|
||||
#include "catch.h"
|
||||
#include "hashtable.h"
|
||||
|
||||
std::vector<int> V{98, 44, 30, 22, 64, 63, 11, 23, 8, 18};
|
||||
|
||||
TEST_CASE("HashTable", "[HASHTABLE]") {
|
||||
|
||||
SECTION("Hashing 10 elements - Size: 20 : Rehashing") {
|
||||
|
||||
HashTable H(20,0.6,1);
|
||||
|
||||
for (unsigned int i = 0; i < V.size(); i++)
|
||||
{
|
||||
H.insert(V.at(i));
|
||||
}
|
||||
H.insert(15);
|
||||
H.insert(16);
|
||||
H.insert(21);
|
||||
H.insert(22);
|
||||
|
||||
if (H.getSize() > 0) {
|
||||
REQUIRE(H.at(3) == 44);
|
||||
REQUIRE(H.at(8) == 8);
|
||||
REQUIRE(H.at(11) == 11);
|
||||
REQUIRE(H.at(15) == 15);
|
||||
REQUIRE(H.at(16) == 98);
|
||||
REQUIRE(H.at(17) == 16);
|
||||
REQUIRE(H.at(18) == 18);
|
||||
REQUIRE(H.at(21) == 21);
|
||||
REQUIRE(H.at(22) == 22);
|
||||
REQUIRE(H.at(23) == 63);
|
||||
REQUIRE(H.at(24) == 64);
|
||||
REQUIRE(H.at(25) == 22);
|
||||
REQUIRE(H.at(26) == 23);
|
||||
REQUIRE(H.at(30) == 30);
|
||||
}
|
||||
REQUIRE(H.getSize() == 41);
|
||||
REQUIRE(H.getCollisionCount() == 8);
|
||||
REQUIRE(H.getElements() == 14);
|
||||
|
||||
}
|
||||
|
||||
SECTION("Hashing 10 elements - quadratisch Sondieren - Size: 15 : Rehashing") {
|
||||
|
||||
HashTable H(15, 0.6, 2);
|
||||
|
||||
for (unsigned int i = 0; i < V.size(); i++)
|
||||
{
|
||||
H.insert(V.at(i));
|
||||
}
|
||||
H.insert(15);
|
||||
H.insert(16);
|
||||
H.insert(21);
|
||||
H.insert(22);
|
||||
|
||||
if (H.getSize() > 0) {
|
||||
REQUIRE(H.at(1) == 63);
|
||||
REQUIRE(H.at(2) == 64);
|
||||
REQUIRE(H.at(5) == 98);
|
||||
REQUIRE(H.at(8) == 8);
|
||||
REQUIRE(H.at(11) == 11);
|
||||
REQUIRE(H.at(13) == 44);
|
||||
REQUIRE(H.at(15) == 15);
|
||||
REQUIRE(H.at(16) == 16);
|
||||
REQUIRE(H.at(18) == 18);
|
||||
REQUIRE(H.at(21) == 21);
|
||||
REQUIRE(H.at(22) == 22);
|
||||
REQUIRE(H.at(23) == 23);
|
||||
REQUIRE(H.at(26) == 22);
|
||||
REQUIRE(H.at(30) == 30);
|
||||
}
|
||||
REQUIRE(H.getSize() == 31);
|
||||
REQUIRE(H.getCollisionCount() == 2);
|
||||
REQUIRE(H.getElements() == 14);
|
||||
}
|
||||
|
||||
SECTION("Hashing 10 elements - doppeltes Hashing- Size: 15 : Rehashing") {
|
||||
|
||||
HashTable H(15, 0.6, 3);
|
||||
|
||||
for (unsigned int i = 0; i < V.size(); i++)
|
||||
{
|
||||
H.insert(V.at(i));
|
||||
}
|
||||
H.insert(15);
|
||||
H.insert(16);
|
||||
H.insert(21);
|
||||
H.insert(22);
|
||||
|
||||
if (H.getSize() > 0) {
|
||||
REQUIRE(H.at(1) == 63);
|
||||
REQUIRE(H.at(2) == 64);
|
||||
REQUIRE(H.at(5) == 98);
|
||||
REQUIRE(H.at(8) == 8);
|
||||
REQUIRE(H.at(11) == 11);
|
||||
REQUIRE(H.at(13) == 44);
|
||||
REQUIRE(H.at(15) == 15);
|
||||
REQUIRE(H.at(16) == 16);
|
||||
REQUIRE(H.at(18) == 18);
|
||||
REQUIRE(H.at(21) == 21);
|
||||
REQUIRE(H.at(22) == 22);
|
||||
REQUIRE(H.at(23) == 23);
|
||||
REQUIRE(H.at(29) == 22);
|
||||
REQUIRE(H.at(30) == 30);
|
||||
}
|
||||
REQUIRE(H.getSize() == 31);
|
||||
REQUIRE(H.getCollisionCount() == 1);
|
||||
REQUIRE(H.getElements() == 14);
|
||||
}
|
||||
}
|
||||
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
Reference in New Issue
Block a user