Actuellement, j'ai une implémentation de table de hachage en C qui utilise des chaînes comme clés et valeurs. Si je voulais stocker des entiers au lieu de chaînes comme valeurs, quelle serait la meilleure façon de le faire? Je pense à stocker l'entier dans une chaîne et à le convertir en entier quand j'en ai besoin, mais cela semble inefficace pour l'arithmétique. Quelque chose commeStocker des entiers dans des tables de hachage implémentées par c?
insert("money", "13");
int i = atoi(get("key1"));
int sum = i + 10;
insert("money", itoa(sum));
Y at-il une meilleure façon de le faire?
EDIT: table de hachage mise en œuvre
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct tableentry /* hashtab entry */
{
struct tableentry *next;
char *key;
char *val;
} tableentry_t;
typedef struct hashtable
{
size_t size;
struct tableentry **tab;
} hashtable_t;
/* creates hashtable */
/* NOTE: dynamically allocated, remember to ht_free() */
hashtable_t *ht_create(size_t size)
{
hashtable_t *ht = NULL;
if ((ht = malloc(sizeof(hashtable_t))) == NULL)
return NULL;
/* allocate ht's table */
if ((ht->tab = malloc(sizeof(tableentry_t) * size)) == NULL)
return NULL;
/* null-initialize table */
int i;
for (i = 0; i < size; i++)
ht->tab[i] = NULL;
ht->size = size;
return ht;
}
/* creates hash for a hashtab */
static unsigned hash(hashtable_t *ht, char *s)
{
unsigned hashval;
for (hashval = 0; *s != '\0'; s++)
hashval = *s + 31 * hashval;
return hashval;
}
/* loops through linked list freeing */
static void te_free(tableentry_t *te)
{
tableentry_t *next;
while (te != NULL)
{
next = te->next;
free(te->key);
free(te->val);
free(te);
te = next;
}
}
/* creates a key-val pair */
static tableentry_t *new(char *k, char *v)
{
tableentry_t *te = NULL;
if ((te = calloc(1, sizeof(*te))) == NULL
|| (te->key = strdup(k)) == NULL
|| (te->val = strdup(v)) == NULL)
{
te_free(te);
return NULL;
}
te->next = NULL;
return te;
}
static tableentry_t *lookup(hashtable_t *ht, char *k)
{
tableentry_t *te;
/* step through linked list */
for (te = ht->tab[hash(ht, k) % ht->size]; te != NULL; te = te->next)
if (strcmp(te->key, k) == 0)
return te; /* found */
return NULL; /* not found */
}
/* inserts the key-val pair */
hashtable_t *ht_insert(hashtable_t *ht, char *k, char *v)
{
tableentry_t *te;
/* unique entry */
if ((te = lookup(ht, k)) == NULL)
{
te = new(k, v);
unsigned hashval = hash(ht, k) % ht->size;
/* insert at beginning of linked list */
te->next = ht->tab[hashval];
ht->tab[hashval] = te;
}
/* replace val of previous entry */
else
{
free(te->val);
if ((te->val = strdup(v)) == NULL)
return NULL;
}
return ht;
}
/* retrieve value from key */
char *ht_get(hashtable_t *ht, char *k)
{
tableentry_t *te;
if ((te = lookup(ht, k)) == NULL)
return NULL;
return te->val;
}
/* frees hashtable created from ht_create() */
void ht_free(hashtable_t *ht)
{
int i;
for (i = 0; i < ht->size; i++)
if (ht->tab[i] != NULL)
te_free(ht->tab[i]);
free(ht);
}
/* resizes hashtable, returns new hashtable and frees old*/
hashtable_t *ht_resize(hashtable_t *oht, size_t size)
{
hashtable_t *nht; /* new hashtable */
nht = ht_create(size);
/* rehash */
int i;
tableentry_t *te;
/* loop through hashtable */
for (i = 0; i < oht->size; i++)
/* loop through linked list */
for (te = oht->tab[i]; te != NULL; te = te->next)
if (ht_insert(nht, te->key, te->val) == NULL)
return NULL;
ht_free(oht);
return nht;
}
utilise simplement C++ une option? : | – Alexander
Je suis confus pourquoi vous ne pouvez pas simplement changer le type de clé en entier, et hacher sur la clé de nombre entier. – Jonesinator
Désolé, je n'étais pas clair. Je veux hacher avec une chaîne (en utilisant le pointeur char comme clé) et stocker un entier (entier est la valeur). L'implémentation de ma table de hachage utilise la chaîne pour les deux. –