How do I iterate and print hashtable in c? - c

The implementation uses a structure similar to the "Static Sequence List" (it uses an array to store the elements). I can insert and query 1 item. But I need to list all the items.
The code:
struct cidade {
int pkCidade;
char nomeCidade[50];
};
struct hashCidade {
int qtdCidade, TABLE_SIZE;
struct cidade **itensCidade;
};
typedef struct hashCidade HashCidade;
HashCidade *createHashCidade(int TABLE_SIZE);
void releaseHashCidade(HashCidade *ha);
int insertHashCidade(HashCidade *ha, struct cidade CidadeH);
int findHashCidade(HashCidade *ha, char *str, struct cidade *CidadeH);
HashCidade *createHashCidade(int TABLE_SIZE) {
HashCidade *ha = (HashCidade*)malloc(sizeof(HashCidade));
if (ha != NULL) {
int i;
ha->TABLE_SIZE = TABLE_SIZE;
ha->itensCidade = (struct cidade **)
malloc(TABLE_SIZE * sizeof(struct cidade*));
if (ha->itensCidade == NULL) {
free(ha);
return NULL;
}
ha->qtdCidade = 0;
for (i = 0; i < ha->TABLE_SIZE; i++)
ha->itensCidade[i] = NULL;
}
return ha;
}
void releaseHashCidade(HashCidade *ha) {
if (ha != NULL) {
int i;
for (i = 0; i < ha->TABLE_SIZE; i++) {
if (ha->itensCidade[i] != NULL)
free(ha->itensCidade[i]);
}
free(ha->itensCidade);
free(ha);
}
}
int insertHashCidade(HashCidade *ha, struct cidade CidadeH) {
if (ha == NULL || ha->qtdCidade == ha->TABLE_SIZE)
return 0;
int chave = valorString(CidadeH.nomeCidade);
int pos = chaveDivisao(chave, ha->TABLE_SIZE);
struct cidade *nova;
nova = (struct cidade *)malloc(sizeof(struct cidade));
if(nova == NULL)
return 0;
*nova = CidadeH;
ha->itensCidade[pos] = nova;
ha->qtdCidade++;
return 1;
}
int findHashCidade(HashCidade *ha, char *str, struct cidade *CidadeH) {
if (ha == NULL)
return 'n';
int chave = valorString(str);
int pos = chaveDivisao(chave, ha->TABLE_SIZE);
if (ha->itensCidade[pos] == NULL)
return 0;
else
*CidadeH = *(ha->itensCidade[pos]);
return 1;
}
Thanks for any help.

It seems to me you can just iterate over the non NULL pointers in the hash array and print the corresponding structure details:
void printCidade(const struct cidade *cp) {
printf("%s\n", cp->nomeCidade);
}
void printHashCidade(const HashCidade *ha) {
if (ha != NULL) {
int i;
for (i = 0; i < ha->TABLE_SIZE; i++) {
if (ha->itensCidade[i] != NULL)
printCidade(ha->itensCidade[i]);
}
}
}

Related

Why is my Hash Map insert function not working?

I am making a Hash Map with people's names as its key using C language. I am using separate chaining to resolve the collision.
This is my code:
#include<stdio.h>
#include<stdlib.h>
#define MinTableSize 1
#include <stdbool.h>
//Colission resolution Using linked list
struct ListNode;
typedef struct ListNode *Position;
struct HashTbl;
typedef struct HashTbl *HashTable;
typedef unsigned int Index;
Index Hash(const char *Key, int Tablesize)
{
unsigned int HashVal = 0;
while(*Key != '\0')
{
HashVal += *Key++;
}
return HashVal % Tablesize;
}
struct ListNode
{
int Element;
Position Next;
};
typedef Position List;
struct HashTbl
{
int TableSize;
List *TheLists;
};
//Function to find next prime number for the size
bool isPrime(int n)
{
if(n <= 1)
{
return false;
}
if(n <= 3)
{
return true;
}
if(n%2 == 0 || n%3 == 0)
{
return false;
}
for(int i = 5; i*i <= n; i = i + 6)
{
if(n%i == 0 || n%(i + 2) == 0)
{
return false;
}
}
return true;
}
int NextPrime(int N)
{
if(N <= 1)
{
return 2;
}
int prime = N;
bool found = false;
while(!found)
{
prime++;
if(isPrime(prime))
{
found = true;
}
}
return prime;
}
HashTable InitializeTable(int TableSize)
{
HashTable H;
int i;
if(TableSize < MinTableSize)
{
printf("Table size is too small\n");
return NULL;
}
H = malloc(sizeof(struct HashTbl));
if(H == NULL)
{
printf("Out of space\n");
return NULL;
}
H->TableSize = NextPrime(TableSize);
H->TheLists = malloc(sizeof(List) * H->TableSize);
if(H->TheLists == NULL)
{
printf("Out of space\n");
return NULL;
}
for(i = 0; i < H->TableSize; i++)
{
H->TheLists[i] = malloc(sizeof(struct ListNode));
if(H->TheLists[i] == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
H->TheLists[i]->Next = NULL;
}
}
return H;
}
//funtion to find the value
Position Find(const char *Key, HashTable H)
{
Position P;
List L;
L = H->TheLists[Hash(Key, H->TableSize)];
P = L->Next;
while(P != NULL && P->Element != Key)
{
P = P->Next;
}
return P;
}
void Insert(const char *Key, HashTable H)
{
Position Pos;
Position NewCell;
List L;
Pos = Find(Key, H);
if(Pos == NULL)
{
NewCell = malloc(sizeof(struct ListNode));
if(NewCell == NULL)
{
printf("Out of space\n");
return NULL;
}
else
{
L = H->TheLists[Hash(Key, H->TableSize)];
NewCell->Next;
NewCell->Element = Key;
L->Next = NewCell;
printf("Key inserted\n");
}
}
else
{
printf("Key already exist\n");
}
}
int main()
{
char Name[6][20] = {"Joshua", "Erica", "Elizabeth", "Monica", "Jefferson", "Andrian"};
int Size = sizeof(Name[0])/sizeof(Name[0][0]);
HashTable H = InitializeTable(Size);
Insert(Name[0], H);
Insert(Name[1], H);
Insert(Name[2], H);
Insert(Name[3], H);
}
The putout of this code is:
Key inserted
Key inserted
This means, it only successfully inserted two keys, while the other name has not been inserted. I think there's some error in my Insert() function, but I got no clue. I tried using an online compiler and it compile properly.

Creating a function to print out the values stored in hash table [duplicate]

The implementation uses a structure similar to the "Static Sequence List" (it uses an array to store the elements). I can insert and query 1 item. But I need to list all the items.
The code:
struct cidade {
int pkCidade;
char nomeCidade[50];
};
struct hashCidade {
int qtdCidade, TABLE_SIZE;
struct cidade **itensCidade;
};
typedef struct hashCidade HashCidade;
HashCidade *createHashCidade(int TABLE_SIZE);
void releaseHashCidade(HashCidade *ha);
int insertHashCidade(HashCidade *ha, struct cidade CidadeH);
int findHashCidade(HashCidade *ha, char *str, struct cidade *CidadeH);
HashCidade *createHashCidade(int TABLE_SIZE) {
HashCidade *ha = (HashCidade*)malloc(sizeof(HashCidade));
if (ha != NULL) {
int i;
ha->TABLE_SIZE = TABLE_SIZE;
ha->itensCidade = (struct cidade **)
malloc(TABLE_SIZE * sizeof(struct cidade*));
if (ha->itensCidade == NULL) {
free(ha);
return NULL;
}
ha->qtdCidade = 0;
for (i = 0; i < ha->TABLE_SIZE; i++)
ha->itensCidade[i] = NULL;
}
return ha;
}
void releaseHashCidade(HashCidade *ha) {
if (ha != NULL) {
int i;
for (i = 0; i < ha->TABLE_SIZE; i++) {
if (ha->itensCidade[i] != NULL)
free(ha->itensCidade[i]);
}
free(ha->itensCidade);
free(ha);
}
}
int insertHashCidade(HashCidade *ha, struct cidade CidadeH) {
if (ha == NULL || ha->qtdCidade == ha->TABLE_SIZE)
return 0;
int chave = valorString(CidadeH.nomeCidade);
int pos = chaveDivisao(chave, ha->TABLE_SIZE);
struct cidade *nova;
nova = (struct cidade *)malloc(sizeof(struct cidade));
if(nova == NULL)
return 0;
*nova = CidadeH;
ha->itensCidade[pos] = nova;
ha->qtdCidade++;
return 1;
}
int findHashCidade(HashCidade *ha, char *str, struct cidade *CidadeH) {
if (ha == NULL)
return 'n';
int chave = valorString(str);
int pos = chaveDivisao(chave, ha->TABLE_SIZE);
if (ha->itensCidade[pos] == NULL)
return 0;
else
*CidadeH = *(ha->itensCidade[pos]);
return 1;
}
Thanks for any help.
It seems to me you can just iterate over the non NULL pointers in the hash array and print the corresponding structure details:
void printCidade(const struct cidade *cp) {
printf("%s\n", cp->nomeCidade);
}
void printHashCidade(const HashCidade *ha) {
if (ha != NULL) {
int i;
for (i = 0; i < ha->TABLE_SIZE; i++) {
if (ha->itensCidade[i] != NULL)
printCidade(ha->itensCidade[i]);
}
}
}

Trying to delete all the elements from HashTable with the status marked as closed

#include<iostream>
using namespace std;
enum Stare {DESCHIS=10, LUCRU=20, DUPLICAT=30, REZOLVAT=40, INCHIS=50};
struct Task
{
char *idTask;
char *data;
char *numeInginer;
int nivelComplexitate;
Stare stare;
};
struct List
{
Task *task;
List*next;
};
struct HashTable
{
List** vector;
int size;
};
List* creareNodLista(Task *task)
{
List*nod = (List*)malloc(sizeof(List));
nod->task = task;
nod->next = NULL;
return nod;
}
void initHashTable(HashTable &hTable, int size)
{
hTable.vector = (List**)malloc(sizeof(List*)*size);
hTable.size = size;
memset(hTable.vector, 0, sizeof(List*)*size);
}
int fhash(char c, int l)
{
return c%l;
}
void inserareNodLista(List*&list, List*nod)
{
nod->next = list;
list = nod;
}
void inserareNodHashTable(HashTable hTable, List*nod)
{ //determinarea pozitiei pe care se face inserarea
int index = fhash(nod->task->numeInginer[0],hTable.size);
//obtinerea listei in care se face inserarea
List*list = hTable.vector[index];
//inserare element nou in lista
inserareNodLista(list, nod);
//actualizare element in hashTable
hTable.vector[index] = list;
}
List* getHashTable(HashTable ht, char cheie)
{
int f = fhash(cheie, ht.size);
return ht.vector[f];
}
void printHashTable(HashTable ht)
{
for (char c = 'A'; c < 'Z'; c++)
{
List*lista = getHashTable(ht, c);
int count = 0;
while (lista)
{
count++;
printf("%d", count);
printf("%s\n", lista->task->idTask);
printf("%s\n", lista->task->data);
printf("%s\n", lista->task->numeInginer);
printf("%d\n", lista->task->nivelComplexitate);
printf("%d\n", lista->task->stare);
lista = lista->next;
}
if (count>1)
printf("\nColiziune\n\n");
}
}
int stergeNodHashTable(HashTable hTable, char*numeInginer)
{
int pozitie = 0;
pozitie = fhash(numeInginer[0], hTable.size);
if (hTable.vector[pozitie] == NULL)
return -1;
else
{
if (strcmp(hTable.vector[pozitie]->task->numeInginer, numeInginer) == 0)
{
if (hTable.vector[pozitie]->next == NULL)
{
free(hTable.vector[pozitie]->task->idTask);
free(hTable.vector[pozitie]->task->data);
free(hTable.vector[pozitie]->task->numeInginer);
free(hTable.vector[pozitie]->task);
free(hTable.vector[pozitie]);
hTable.vector[pozitie] = NULL;
}
else
{
List*lista = hTable.vector[pozitie];
hTable.vector[pozitie] = lista->next;
free(lista->task->idTask);
free(lista->task->data);
free(lista->task->numeInginer);
free(lista->task);
free(lista);
lista->next = NULL;
lista = NULL;
}
}
else
{
List*tmp = hTable.vector[pozitie];
while (tmp->next != NULL && strcmp(tmp->next->task->numeInginer, numeInginer) != 0)
tmp = tmp->next;
List*list = tmp->next;
if (list->next == NULL)
{
free(list->task->idTask);
free(list->task->numeInginer);
free(list->task->data);
free(list->task);
free(list);
tmp->next = NULL;
list = NULL;
}
else
{
List*tmp = list;
list = list->next;
free(tmp->task->idTask);
free(tmp->task->data);
free(tmp->task->numeInginer);
free(tmp->task);
free(tmp);
tmp->next = NULL;
tmp = NULL;
}
}
}
return pozitie;
}
void main()
{
FILE *pFile = fopen("Text.txt", "r");
Task *task = NULL;
HashTable ht;
initHashTable(ht, 29);
if (pFile)
{
while (!feof(pFile))
{
task = (Task*)malloc(sizeof(Task));
char id[50];
fscanf(pFile, "%s", &id);
task->idTask = (char*)malloc(strlen(id) + 1);
strcpy(task->idTask, id);
char data[50];
fscanf(pFile, "%s", data);
task->data = (char*)malloc(strlen(data) + 1);
strcpy(task->data, data);
char numeInfiner[50];
fscanf(pFile, "%s", numeInfiner);
task->numeInginer = (char*)malloc(strlen(numeInfiner) + 1);
strcpy(task->numeInginer, numeInfiner);
fscanf(pFile, "%d", &task->nivelComplexitate);
fscanf(pFile, "%d", &task->stare);
//creare element lista
List*nod = creareNodLista(task);
//inserare element in hashTable
inserareNodHashTable(ht, nod);
}
fclose(pFile);
for (char c = 'A'; c < 'Z'; c++)
{
List *lista = getHashTable(ht, c);
while (lista)
{
if (lista->task->stare == 50)
stergeNodHashTable(ht, lista->task->numeInginer);
}
}
printHashTable(ht);
}
}
I am trying to delete from hashTable all the elements with status marked as closed. The delete function is working fine but when i call it for al the hashtable, it got me error: lista->task was 0xDDDDDD. I cant understand why. Please help me!

Setting struct value = segfault

#include <stdio.h>
#include <stdlib.h>
#define true 1
struct hashRow {
char *key;
char *value;
};
struct hash_table {
int max;
int number_of_elements;
struct hashRow **elements;
};
int hashstring(const char *s)
{
int key = 0;
while (*s)
key = key * 37 + *s++;
return key;
}
int hash_fun(int key, int try, int max) {
return (key + try) % max;
}
struct hash_table *table;
int hash_insert(struct hashRow *data, struct hash_table *hash_table) {
int try, hash;
if(hash_table->number_of_elements < hash_table->max) {
return 0; // FULL
}
for(try = 0; true; try++) {
int hkey = hashstring(data->key);
hash = hash_fun(hkey, try, hash_table->max);
if(hash_table->elements[hash] == 0) { // empty cell
hash_table->elements[hash] = data;
hash_table->number_of_elements++;
return 1;
}
}
return 0;
}
struct hashRow *hash_retrieve(char *key, struct hash_table *hash_table) {
int try, hash;
for(try = 0; true; try++) {
int hkey = hashstring(key);
hash = hash_fun(hkey, try, hash_table->max);
if(hash_table->elements[hash] == 0) {
return 0; // Nothing found
}
if(hash_table->elements[hash]->key == key) {
return hash_table->elements[hash];
}
}
return 0;
}
int hash_delete(char *key, struct hash_table *hash_table) {
int try, hash;
for(try = 0; true; try++) {
int hkey = hashstring(key);
hash = hash_fun(hkey, try, hash_table->max);
if(hash_table->elements[hash] == 0) {
return 0; // Nothing found
}
if(hash_table->elements[hash]->key == key) {
hash_table->number_of_elements--;
hash_table->elements[hash] = 0;
return 1; // Success
}
}
return 0;
}
void insertsomething()
{
struct hashRow *toInsert;
toInsert = (struct hashRow *)malloc(sizeof(*toInsert));
printf("toInsert declared\n");
char *k = (char*)malloc(sizeof(char*));
char *v = (char*)malloc(sizeof(char*));
k = "sayhello";
v = "hello";
this is where I seem to be having the problem.
toInsert->key = k;
toInsert->value = v;
hash_insert(toInsert, table);
}
int main()
{
printf("calling insertsomething.\n");
insertsomething();
struct hashRow *gotten;
gotten = hash_retrieve("sayhello", table);
printf("test: %s\n", gotten->value);
}
I'm trying to create a hash table, but whenever I try to set a value in the toInsert struct pointer it segfaults. Can someone explain to me what I am doing wrong?
Try this:
void insertsomething()
{
struct hashRow *toInsert;
toInsert = (struct hashRow *)malloc(sizeof(*toInsert));
printf("toInsert declared\n");
/*
char *k = (char*)malloc(sizeof(char*)); // wrong size
char *v = (char*)malloc(sizeof(char*)); // wrong size
k = "sayhello"; // bad assignment
v = "hello"; // bad assignment
*/
toInsert->key = strdup("sayhello");
toInsert->value = strdup("hello");
hash_insert(toInsert, table);
}
Also, I can't spot where you reserve memory for your hash_table. Is it hidden somewhere else??

Problems with this stack implementation

where is the mistake?
My code here:
typedef struct _box
{
char *dados;
struct _box * proximo;
} Box;
typedef struct _pilha
{
Box * topo;
}Stack;
void Push(Stack *p, char * algo)
{
Box *caixa;
if (!p)
{
exit(1);
}
caixa = (Box *) calloc(1, sizeof(Box));
caixa->dados = algo;
caixa->proximo = p->topo;
p->topo = caixa;
}
char * Pop(Stack *p)
{
Box *novo_topo;
char * dados;
if (!p)
{
exit(1);
}
if (p->topo==NULL)
return NULL;
novo_topo = p->topo->proximo;
dados = p->topo->dados;
free(p->topo);
p->topo = novo_topo;
return dados;
}
void StackDestroy(Stack *p)
{
char * c;
if (!p)
{
exit(1);
}
c = NULL;
while ((c = Pop(p)) != NULL)
{
free(c);
}
free(p);
}
int main()
{
int conjunto = 1;
char p[30], * v;
int flag = 0;
Stack *pilha = (Stack *) calloc(1, sizeof(Stack));
FILE* arquivoIN = fopen("L1Q3.in","r");
FILE* arquivoOUT = fopen("L1Q3.out","w");
if (arquivoIN == NULL)
{
printf("Erro na leitura do arquivo!\n\n");
exit(1);
}
fprintf(arquivoOUT,"Conjunto #%d\n",conjunto);
while (fscanf(arquivoIN,"%s", p) != EOF )
{
if (pilha->topo == NULL && flag != 0)
{
conjunto++;
fprintf(arquivoOUT,"\nConjunto #%d\n",conjunto);
}
if(strcmp(p, "return") != 0)
{
Push(pilha, p);
}
else
{
v = Pop(pilha);
if(v != NULL)
{
fprintf(arquivoOUT, "%s\n", v);
}
}
flag = 1;
}
StackDestroy(pilha);
return 0;
}
The Pop function returns the string value read from file.
But is not correct and i don't know why.
You're not allocating any storage for the strings pointed to by dados - you're just re-using one string buffer (p) and passing that around, so all your stack elements just point to this one string.

Resources