Как начинающий программист, я начал читать Язык программирования C * , чтобы узнать больше о pointers
и structs
.
В настоящее время я изучаю хеш-карты в C. Следуя примеру из книги, я создал свою собственную хеш-карту для хранения пар ключ-значение:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STRING_SIZE 100
#define HASHSIZE 101
static struct map *hashtab[HASHSIZE]; /* pointer table */
unsigned hash(char *); /* hashing function: form hash value for string s. used by both lookup and install*/
char *strdup(char *);
struct map { /* creating a map structure */
struct map *next;
char *KEY; /* KEY - pointer to a char - member of nlist*/
char *object1; /* object - pointer to a char - member of nlist*/
};
/* lookup function takes a pointer to char - s as an argument and returns a pointer to map structure */
struct map *lookup(char *s) {
struct map *np;
for (np = hashtab[hash(s)]; np != NULL; np = np->next) {
if (strcmp(s, np->KEY) == 0) {
return np;
}
}
return NULL;
}
/* install function takes a pointer to a char - KEY, object and returns a pointer to map structure */
struct map *install(char *KEY, char *object1) {
/* install: put (name, defn) in */
/* Install uses lookup to determine whether the KEY being installed
is already present. Proceeds to create a new entry or update*/
struct map *np;
unsigned hashval;
if ((np = lookup(KEY)) == NULL) {
np = (struct map *) malloc(sizeof(*np));
if (np == NULL || (np->KEY = strdup(KEY)) == NULL) {
return NULL;
}
hashval = hash(KEY);
np->next = hashtab[hashval];
hashtab[hashval] = np;
}
else {
free((void *)np->object1);
}
if ((np->object1 = strdup(object1)) == NULL) {
return NULL;
}
return np;
}
Затем я назначаю значения клавишам следующим образом:
int main(void) {
struct map *table[4] = {
(install("key1", "value1")),
(install("key2", "value2")),
(install("key3", "value3")),
(install("key4", "value4"))
};
int i;
for (i = 0; i < 4; i++) {
printf("%s->%s\n", table[i]->KEY, table[i]->object);
}
printf("\n");
return 0;
}
Код выше работает хорошо, я могу назначить value1
, ..., value4
для key1
, ..., key4
соответственно. Однако это не позволяет мне назначать несколько значений одному ключу.
Допустим, я прочитал следующее из текстового файла:
key1 9000 600 Test1
key2 2000 600 Test2
key3 3000 120 Test3
key4 4000 120 Test4
.
.
key10 1000 560 Test10
Я хочу иметь возможность хранить каждую клавишу и назначать ей несколько значений. Поскольку число столбцов фиксировано, возможно, я мог бы создать структуру, представляющую строку, и поместить ее в карту.
Для этого необходимо изменить install
, чтобы можно было добавить несколько значений для одного и того же ключа. Поскольку ключи уникальны, lookup
и uninstall
(функция, которую я создал для удаления ключей) должны остаться без изменений.
Приведенный выше код работает отлично, однако я ищу общее решение для добавления нескольких значений к одним и тем же ключам.
Как мне поступить, чтобы можно было звонить:
struct map *table[4] = {
(install("key1", "9000" ,"600", "Test1")), //key, object1, object2, object3
(install("key2", "2000" ,"600", "Test2")),
(install("key3", "3000" ,"120", "Test3")),
(install("key4", "4000" ,"120", "Test4"))
};
Другая идея была бы:
/* key points to this struct */
struct Value {
int i;
int k;
char *c;
};
typedef struct map { /* creating a map structure */
struct map *next;
char *KEY;
struct Value value; /* place multiple values inside a struct*/
};
и вот где я застреваю:
struct map *insert(char *KEY, struct *Value) {
struct map *np;
unsigned hashval;
if ((np = lookup(KEY)) == NULL) {
np = (struct map *) malloc(sizeof(*np));
if (np == NULL || (np->KEY = strdup(KEY)) == NULL) {
return NULL;
}
hashval = hash(KEY);
np->next = hashtab[hashval];
hashtab[hashval] = np;
}
else {
free((struct Value*)np->value); //type cast cannot convert from 'Value' to 'Value*'
}
if ((np->Value = strdup(Value)) == NULL) { //map has no field value
return NULL;
}
return np;
}
Я искал следующие вопросы, но не смог извлечь соответствующую информацию о том, как реализовать это в C.
Хеш-карты, имеющие несколько ключей с несколькими значениями
Как назначить несколько значений хеш-ключу?
HashMap с многозначными ключами
Как я могу реализовать хэш-карту, которая принимает несколько значений, назначенных одной и той же клавише?
EDIT
Как указано в комментариях, структура, которую я использую, может быть не хеш-картой, а связанным списком. Однако книга специально говорит, что страница 144 - это хэш-карта.