C中字符串数组作为值的Hashmap

C中字符串数组作为值的Hashmap,c,database,hashmap,tuples,hashtable,C,Database,Hashmap,Tuples,Hashtable,我正在用C语言编写一个程序,它读取数据库文件并将其转换为一些C结构 是否可以实现一个使用int作为键并返回字符串数组(char**)作为值的哈希表(这是通过id检索数据库中的某个元组) 谢谢 是的,这是可能的。但这取决于钥匙的性质。如果找不到键如何映射到值的模式,则很难实现哈希函数。一种方法是针对键实现高度平衡的二叉搜索树,并存储值。这将保证每个操作的最坏情况时间复杂度为O(logn)。是的,您可以,这里是使用SuperFash(代码中的注释)的示例: #包括 #包括 #包括 #包括 typed

我正在用C语言编写一个程序,它读取数据库文件并将其转换为一些C结构


是否可以实现一个使用int作为键并返回字符串数组(char**)作为值的哈希表(这是通过id检索数据库中的某个元组)


谢谢

是的,这是可能的。但这取决于钥匙的性质。如果找不到键如何映射到值的模式,则很难实现哈希函数。一种方法是针对键实现高度平衡的二叉搜索树,并存储值。这将保证每个操作的最坏情况时间复杂度为O(logn)。

是的,您可以,这里是使用SuperFash(代码中的注释)的示例:

#包括
#包括
#包括
#包括
typedef结构数据{
整数指数;
字符名[16];
结构数据*下一步;
}数据;
外部字符*strdup(常量字符*);
#定义get16位(d)(((uint32_t)((const uint8_t*)(d))[1])=2;
/*主回路*/
对于(;len>0;len--){
哈希+=(获取16位(数据));
tmp=(获取16位(数据+2)11;
}
/*处理最终案例*/
开关(rem){
案例3:
哈希+=获取16位(数据);
散列^=散列11;
打破
案例2:
哈希+=获取16位(数据);
hash^=hash>17;
打破
案例1:
散列+=(有符号字符)*数据;
hash^=hash>1;
}
/*最后127位的强制“雪崩”*/
hash^=hash>5;
hash^=hash>17;
hash^=hash>6;
返回散列;
}
/*返回数据(如果存在,则为空)*/
数据*插入(数据**表格,数据*值,大小)
{
uint32_t散列;
数据*温度;
chars[10];
内伦;
/*将索引转换为字符串*/
len=sprintf(s,“%d”,值->索引);
散列=超级散列(s,len)%n;
if(表[hash]==NULL){
/*找不到,请插入*/
表[hash]=值;
}否则{
temp=表[hash];
而(1){
if(temp==value)返回NULL;
如果(临时->下一步){
温度=温度->下一步;
}否则就断了;
}
/*找不到,请插入*/
温度->下一步=数值;
}
返回值;
}
/*以字符串数组形式返回数据(如果未找到,则返回NULL)*/
字符**搜索(数据**表格、整数索引、大小)
{
字符**记录;
uint32_t散列;
数据*温度;
chars[10];
内伦;
/*将索引转换为字符串*/
len=sprintf(s,“%d”,索引);
散列=超级散列(s,len)%n;
if(表[hash]!=NULL){
temp=表[hash];
while(临时){
如果(临时->索引==索引){
/*字符串数组的结构(检查mallocs)*/
记录=malloc(sizeof(*记录)*2);
记录[0]=strdup;
记录[1]=strdup(临时->名称);
返回记录;
}
温度=温度->下一步;
}
}
/*找不到*/
返回NULL;
}
无效自由记录(字符**记录)
{
自由(记录[0]);
免费(记录[1]);
免费(记录);
}
内部主(空)
{
数据值[]={
{4611,“凯西”,空},
{5141,“内维尔”,空},
{6484,“多米尼克”,空},
{2074,“凯利”,空},
{9969,“佩特拉”,空},
{9663,“劳拉”,空},
{6136,“Bianca”,NULL},
{1647,“奥雷利亚”,空},
{8512,“Britanney”,NULL},
{2613,“奥普拉”,空},
{2610,“Shay”,NULL},
{6591,“拉尔夫”,空},
{9302,“慈善”,空},
{2593,“莉莉安”,空},
{9732,“Hop”,NULL}
};
size_t i,n=sizeof(值)/sizeof(值[0]);
/*指向值的指针数组*/
数据**表格=calloc(n,sizeof(*表格));
/*值作为字符串数组*/
字符**记录;
如果(表==NULL){
perror(“calloc”);
退出(退出失败);
}
放入(“插入…”);
对于(i=0;i

但正如Rikayan所指出的,平衡二叉搜索树是最好的选择。

你想知道如何用C实现SQL数据库吗?只要使用已经可用的解决方案,比如“是否可以实现一个使用int作为键并返回字符串数组(char**)作为值的哈希表”—在软件中没有什么是不可能的。(投票被否决,因为这是一个“为我写代码”的非问题。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

typedef struct data {
    int index;
    char name[16];
    struct data *next;
} data;

extern char *strdup(const char *);

#define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
                       +(uint32_t)(((const uint8_t *)(d))[0]))

uint32_t SuperFastHash(const char * data, int len)
{
    uint32_t hash = len, tmp;
    int rem;

    if (len <= 0 || data == NULL) return 0;

    rem = len & 3;
    len >>= 2;

    /* Main loop */
    for (;len > 0; len--) {
        hash  += (get16bits(data));
        tmp    = (get16bits(data + 2) << 11) ^ hash;
        hash   = (hash << 16) ^ tmp;
        data  += 2 * sizeof(uint16_t);
        hash  += hash >> 11;
    }

    /* Handle end cases */
    switch (rem) {
        case 3:
            hash += get16bits(data);
            hash ^= hash << 16;
            hash ^= ((signed char)data[sizeof(uint16_t)]) << 18;
            hash += hash >> 11;
            break;
        case 2:
            hash += get16bits(data);
            hash ^= hash << 11;
            hash += hash >> 17;
            break;
        case 1:
            hash += (signed char)*data;
            hash ^= hash << 10;
            hash += hash >> 1;
    }

    /* Force "avalanching" of final 127 bits */
    hash ^= hash << 3;
    hash += hash >> 5;
    hash ^= hash << 4;
    hash += hash >> 17;
    hash ^= hash << 25;
    hash += hash >> 6;

    return hash;
}

/* return data (or NULL if exists) */
data *insert(data **table, data *value, size_t n)
{
    uint32_t hash;
    data *temp;
    char s[10];
    int len;

    /* convert index to string */
    len = sprintf(s, "%d", value->index);
    hash = SuperFastHash(s, len) % n;
    if (table[hash] == NULL) {
        /* not found, insert */
        table[hash] = value;
    } else {
        temp = table[hash];
        while (1) {
            if (temp == value) return NULL;
            if (temp->next) {
                temp = temp->next;
            } else break;
        }
        /* not found, insert */
        temp->next = value;
    }
    return value;
}

/* return data as array of strings (or NULL if not found) */
char **search(data **table, int index, size_t n)
{
    char **record;
    uint32_t hash;
    data *temp;
    char s[10];
    int len;

    /* convert index to string */
    len = sprintf(s, "%d", index);
    hash = SuperFastHash(s, len) % n;
    if (table[hash] != NULL) {
        temp = table[hash];
        while (temp) {
            if (temp->index == index) {
                /* struct to array of strings (check mallocs) */
                record = malloc(sizeof(*record) * 2);
                record[0] = strdup(s);
                record[1] = strdup(temp->name);
                return record;
            }
            temp = temp->next;
        }
    }
    /* not found */
    return NULL;
}

void free_record(char **record)
{
    free(record[0]);
    free(record[1]);
    free(record);
}

int main(void)
{
    data values[] = {
        {4611, "Kessie", NULL},
        {5141, "Neville", NULL},
        {6484, "Dominic", NULL},
        {2074, "Kelly", NULL},
        {9969, "Petra", NULL},
        {9663, "Laura", NULL},
        {6136, "Bianca", NULL},
        {1647, "Aurelia", NULL},
        {8512, "Britanney", NULL},
        {2613, "Oprah", NULL},
        {2610, "Shay", NULL},
        {6591, "Ralph", NULL},
        {9302, "Charity", NULL},
        {2593, "Lillian", NULL},
        {9732, "Hop", NULL}
    };
    size_t i, n = sizeof(values) / sizeof(values[0]);
    /* array of pointers to values */
    data **table = calloc(n, sizeof(*table));
    /* value as array of strings */
    char **record;

    if (table == NULL) {
        perror("calloc");
        exit(EXIT_FAILURE);
    }
    puts("Inserting ...");
    for (i = 0; i < n; i++) {
        printf("%d %s\n", values[i].index, values[i].name);
        insert(table, &values[i], n);
    }
    if (!insert(table, &values[1], n)) puts("Exists");
    puts("Searching ...");
    for (i = 2610; i < 2615; i++) {
        record = search(table, i, n);
        if (record == NULL) {
            printf("%zu Not found\n", i);
        } else {
            printf("%s %s\n", record[0], record[1]);
            free_record(record);
        }
    }
    free(table);
    return 0;
}