Cod sursa(job #1415762)

Utilizator McVxCretu Alexandru McVx Data 6 aprilie 2015 05:54:35
Problema Hashuri Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 5.2 kb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct cell
{
	struct cell *next;
	void *info;
} TCell, *TList;

typedef void (*TFPrintElem)(void*);
typedef void (*TFreeInfo)(void*);

int list_insert(TList *list, void *info, size_t infoSize);         
void list_remove(TList *elem, TFreeInfo freeInfo);
void list_destroy(TList *list, TFreeInfo freeInfo);
size_t list_length(TList *list);
void list_print(TList *list, TFPrintElem print_elem);

typedef struct
{
	int *key;
	void *value;
} TPair;

typedef struct
{
	int N;
	TList* v;
} THashTable;

int __hashTable_hash(int *key, int N);
int __hashTable_keyCompare(void *keyA, void *keyB);
THashTable* hashTable_new(int N);
void hashTable_destroy(THashTable **ht, TFreeInfo freePair);
int hashTable_insert(THashTable *ht, int *key, void *value, size_t valueSize);
int hashTable_remove(THashTable *ht, int *key, TFreeInfo freePair);
void* hashTable_value(THashTable *ht, int *key);
int hashTable_hasKey(THashTable *ht, int *key);
void hashTable_print(THashTable *ht, TFPrintElem print_elem);
void hashTable_printBucket(THashTable *ht, int bucket, TFPrintElem print_elem);

void free_pair(void *p)
{
	TPair *pair = p;
	free(pair->key);
	free(pair->value);
	free(pair);
}

void print_pair(void *p)
{
	TPair *pair = p;
	printf("(%d %d) ", *pair->key, *(int*)pair->value);
}

int main(void)
{
	int command, key, N;

	freopen("hashuri.in", "r", stdin);
	freopen("hashuri.out", "w", stdout);

	THashTable *ht = hashTable_new(666013);

	for (scanf("%d", &N); N; N--)
	{
		scanf("%d %d", &command, &key);
		if (command == 1)
		{
			int value = 1;
			hashTable_insert(ht, &key, &value, sizeof(int));
			continue;
		}
		if (command == 2)
		{
			hashTable_remove(ht, &key, free_pair);
			continue;
		}
		printf("%d\n", hashTable_hasKey(ht, &key));
	}

	//hashTable_print(ht, print_pair);

	//hashTable_destroy(&ht, free_pair);

	return 0;
}

int list_insert(TList *list, void *info, size_t infoSize)
{
    TList aux = calloc(1, sizeof(TCell));
    aux->info = calloc(1, infoSize);

    memcpy(aux->info, info, infoSize);
    aux->next = *list;
    *list = aux;

    return 1;
}

void list_remove(TList *elem, TFreeInfo freeInfo)
{
    TList aux = *elem;

    freeInfo(aux->info);
    *elem = aux->next;
    free(aux);
}

void list_destroy(TList *list, TFreeInfo freeInfo)
{
    while (*list != NULL)
    {
        list_remove(list, freeInfo);
    }
}

size_t list_length(TList *list)
{
    size_t lg = 0;
    TList p = *list;

    for ( ; p != NULL; p = p->next)
    {
        lg++;
    }

    return lg;
}

void list_print(TList *list, TFPrintElem print_elem)
{ 
    if (!*list)
    {
        printf("VIDA\n");
        return;
    }

    for ( ; *list != NULL; list = &(*list)->next)
    {
        print_elem((*list)->info);
    }
    
    printf("\n");
}

int __hashTable_hash(int *key, int N)
{
	return *key % N;
}

int __hashTable_keyCompare(void *keyA, void *keyB)
{
	return *(int*)keyA - *(int*)keyB;
}

THashTable* hashTable_new(int N)
{
	THashTable *ht = calloc(1, sizeof(THashTable));
	if (!ht)
	{
		return NULL;
	}

	ht->N = N;
	ht->v = calloc(N, sizeof(TList));
	if (!ht->v)
	{
		free(ht);
		return NULL;
	}

	return ht;
}

void hashTable_destroy(THashTable **ht, TFreeInfo freePair)
{
	int i;
	TList l;

	for (i = 0; i < (*ht)->N; i++)
	{
	    l = (*ht)->v[i];
	    list_destroy(&l, freePair);
	}

	free((*ht)->v);
	free(*ht);

	*ht = NULL;
}

int hashTable_insert(THashTable *ht, int *key, void *value, size_t valueSize)
{
	int p = __hashTable_hash(key, ht->N);
	TList *l = &ht->v[p];

	int ok = -1;
	while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
	{
		l = &(*l)->next;
	}

	if (ok == 0)
	{
		return 0;
	}

	TPair *pair = calloc(1, sizeof(TPair));
	pair->key = calloc(1, sizeof(int));
	pair->value = calloc(1, valueSize);

	memcpy(pair->key, key, sizeof(int));
	memcpy(pair->value, value, valueSize);

	TList aux = calloc(1, sizeof(TCell));
	aux->next = *l;
	aux->info = pair;
	*l = aux;

	return 1;
}

int hashTable_remove(THashTable *ht, int *key, TFreeInfo freePair)
{
	int p = __hashTable_hash(key, ht->N);
	TList *l = &ht->v[p];

	int ok = -1;
	while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
	{
		l = &(*l)->next;
	}

	if (ok == 0)
	{
		list_remove(l, freePair);
		return 1;
	}

	return 0;
}

void* hashTable_value(THashTable *ht, int *key)
{
	int p = __hashTable_hash(key, ht->N);
	TList *l = &ht->v[p];

	int ok = -1;
	while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
	{
		l = &(*l)->next;
	}

	if (ok == 0)
	{
		return ((TPair*)(*l)->info)->value;
	}

	return NULL;
}

int hashTable_hasKey(THashTable *ht, int *key)
{
	int p = __hashTable_hash(key, ht->N);
	TList *l = &ht->v[p];

	int ok = -1;
	while (*l != NULL && (ok = __hashTable_keyCompare(((TPair*)(*l)->info)->key, key)) < 0)
	{
		l = &(*l)->next;
	}

	return (ok == 0);
}

void hashTable_print(THashTable *ht, TFPrintElem print_elem)
{
	int i;
	TList l;

	for (i = 0; i < ht->N; i++)
	{
		l = ht->v[i];

		if (!l)
		{
			continue;
		}

		printf("%d: ", i);
		list_print(&l, print_elem);
	}
}

void hashTable_printBucket(THashTable *ht, int bucket, TFPrintElem print_elem)
{
	if (bucket >= ht->N)
	{
		return;
	}

	TList *l = &ht->v[bucket];
	list_print(l, print_elem);
}