HashTable works (tm)

This commit is contained in:
Benjamyn Love 2023-12-06 20:58:05 +11:00
parent f17cc04b49
commit 2609191422

View File

@ -5,9 +5,10 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <math.h> #include <math.h>
#include <time.h>
// https://www.digitalocean.com/community/tutorials/hash-table-in-c-plus-plus // https://www.digitalocean.com/community/tutorials/hash-table-in-c-plus-plus
#define CAPACITY 5000 // Size of the hashtable #define CAPACITY 8000000 // Size of the hashtable
struct Ht_entry struct Ht_entry
{ {
@ -16,30 +17,102 @@ struct Ht_entry
struct HashTable struct HashTable
{ {
struct Ht_entry **entry; struct Ht_entry **entries;
int size; int size;
int count; int count;
}; };
unsigned long unsigned long
hash_function(int x, int y, char *c, int r) hash_function(int x, int y, int num)
{ {
unsigned long i = 0; unsigned long i = 0;
int str_total = 0;
for (int j = 0; j < r; j++) i = (((x + 1) * num) - y);
{
str_total += (int)c[j];
}
i = x * y - (int)str_total;
return i % CAPACITY; return i % CAPACITY;
} }
struct Ht_entry create_item(int x, int y, int num) struct Ht_entry *create_item(int x, int y, int num)
{ {
// Creates a pointer to the a new HashTable item // Creates a pointer to the a new HashTable item
struct Ht_entry *entry = (struct Ht_entry *)malloc(sizeof(struct Ht_entry)); struct Ht_entry *entry = (struct Ht_entry *)malloc(sizeof(struct Ht_entry));
entry->num = malloc(sizeof(num)); entry->num = (int)malloc(sizeof(num));
int nDigits = floor(log10(abs(num))) + 1; // int nDigits = floor(log10(abs(num))) + 1;
entry->num = num;
return entry;
}
void free_entry(struct Ht_entry *entry)
{
free(entry->num);
free(entry);
}
void free_table(struct HashTable *table)
{
for (int i = 0; i < table->size; i++)
{
struct Ht_entry *entry = table->entries[i];
if (table != NULL)
{
free_entry(entry);
}
}
free(table->entries);
free(table);
}
void ht_insert(struct HashTable *table, int x, int y, int num)
{
struct Ht_entry *entry = create_item(x, y, num);
int index = hash_function(x, y, num);
struct Ht_entry *current_item = table->entries[index];
if (current_item == NULL)
{
if (table->count == table->size)
{
printf("Hash table full ;|\n");
free_entry(entry);
return;
}
table->entries[index] = entry;
table->count++;
}
else
{
printf("Collision at %i, %i, %i, %i\n", index, x, y, num);
// printf("HASH COLISION, MAYDAY MAYDAY!\n");
// exit(2);
}
}
struct HashTable *create_table(int size)
{
struct HashTable *table = (struct HashTable *)malloc(sizeof(struct HashTable));
table->size = size;
table->count = 0;
table->entries = (struct Ht_entry **)calloc(table->size, sizeof(struct Ht_entry *));
for (int i = 0; i < table->size; i++)
{
table->entries[i] = NULL;
}
return table;
}
int ht_search(struct HashTable *table, int x, int y, int num)
{
int index = hash_function(x, y, num);
struct Ht_entry *entry = table->entries[index];
if (entry != NULL)
{
return entry->num;
}
return NULL;
} }
int simple_int_conv(char str) int simple_int_conv(char str)
@ -52,7 +125,7 @@ int simple_int_conv(char str)
return -69420; return -69420;
} }
char *check_numbers_around(int x, int y, char chars[140][141]) char *check_numbers_around(int x, int y, char chars[140][141], struct HashTable *table)
{ {
char *found_str; char *found_str;
// printf("%c", chars[x][y]); // printf("%c", chars[x][y]);
@ -64,7 +137,7 @@ char *check_numbers_around(int x, int y, char chars[140][141])
} }
if (isdigit(num) == 0) if (isdigit(num) == 0)
{ {
printf("Is a number: %i\n", num); ht_insert(table, x, y, num);
} }
if (1) if (1)
{ {
@ -72,7 +145,7 @@ char *check_numbers_around(int x, int y, char chars[140][141])
return found_str; return found_str;
} }
void check_symbols(int x, int y, char chars[140][141]) void check_symbols(int x, int y, char chars[140][141], struct HashTable *table)
{ {
char *symbols = "*$%&/@-=+#"; char *symbols = "*$%&/@-=+#";
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
@ -81,7 +154,7 @@ void check_symbols(int x, int y, char chars[140][141])
if (chars[x][y] == symbols[i] || chars[x][y] == '1') if (chars[x][y] == symbols[i] || chars[x][y] == '1')
{ {
check_numbers_around(x, y, chars); check_numbers_around(x, y, chars, table);
// printf("\n\nGot a symbol: %c\n\n", chars[x][y]); // printf("\n\nGot a symbol: %c\n\n", chars[x][y]);
exit(0); exit(0);
} }
@ -90,9 +163,19 @@ void check_symbols(int x, int y, char chars[140][141])
int main() int main()
{ {
struct HashTable *table = create_table(CAPACITY);
srand(time(NULL));
char *filename = "input"; char *filename = "input";
struct OpenFile *o_file = load_file_to_mem(filename); struct OpenFile *o_file = load_file_to_mem(filename);
for (int i = 0; i < 50; i++)
{
for (int j = 0; j < 50; j++)
{
// printf("Adding %i, %i, %i\n", i, j, 243);
ht_insert(table, i, j, rand());
}
}
// Load the dataset into memory so we have the full data mapped // Load the dataset into memory so we have the full data mapped
// in an easy to work with way // in an easy to work with way
const int line_length = 141; const int line_length = 141;
@ -124,7 +207,7 @@ int main()
for (int j = 0; j < line_length; j++) for (int j = 0; j < line_length; j++)
{ {
// printf("%c", chars[i][j]); // printf("%c", chars[i][j]);
check_symbols(i, j, chars); check_symbols(i, j, chars, table);
// if (j % line_length == 0) // if (j % line_length == 0)
// { // {