C 语言实现 C# 中的泛型 Dictionary

好的,下面是一个简单的用 C 语言实现 C# 中的泛型 Dictionary 的示例代码,代码中有详细的注释,帮助你理解代码的实现细节。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 定义一个泛型键值对的结构体
typedef struct KeyValuePair {
    
    
    void *key;   // 用 void * 存储键
    void *value; // 用 void * 存储值
} KeyValuePair;

// 定义一个泛型字典的结构体
typedef struct Dictionary {
    
    
    KeyValuePair *items; // 用键值对结构体存储字典的元素
    size_t size; // 存储键的大小
    size_t count; // 存储元素的数量
    size_t capacity; // 存储字典的容量
} Dictionary;

// 定义一个哈希函数,用于计算键的哈希值
unsigned int Dictionary_HashFunction(Dictionary *dictionary, void *key) {
    
    
    // 将键的字节数据转换为 unsigned int 类型
    unsigned int hash = 0;
    unsigned char *p = (unsigned char *)key;
    for (size_t i = 0; i < dictionary->size; i++) {
    
    
        hash = 31 * hash + *p;
        p++;
    }
    return hash;
}

// 初始化一个泛型字典
Dictionary *Dictionary_Init(size_t size) {
    
    
    Dictionary *dictionary = malloc(sizeof(Dictionary)); // 为字典结构体分配内存
    dictionary->items = malloc(sizeof(KeyValuePair) * 4); // 为字典元素分配内存
    dictionary->size = size; // 存储键的大小
    dictionary->count = 0; // 初始化元素数量为 0
    dictionary->capacity = 4; // 初始化字典容量为 4
    return dictionary; // 返回字典结构体的指针
}

// 向泛型字典中添加一个键值对
void Dictionary_Add(Dictionary *dictionary, void *key, void *value) {
    
    
    // 如果字典的元素数量等于字典的容量,需要扩容
    if (dictionary->count == dictionary->capacity) {
    
    
        dictionary->capacity *= 2; // 容量扩大为原来的 2 倍
        dictionary->items = realloc(dictionary->items, sizeof(KeyValuePair) * dictionary->capacity); // 重新分配内存
    }
    // 计算键的哈希值
    unsigned int hash = Dictionary_HashFunction(dictionary, key);
    // 如果哈希值对应的元素已经存在,需要替换值
    for (size_t i = 0; i < dictionary->count; i++) {
    
    
        if (dictionary->items[i].key != NULL && memcmp(dictionary->items[i].key, key, dictionary->size) == 0) {
    
    
            dictionary->items[i].value = value; // 替换值
            return;
        }
    }
    // 如果哈希值对应的元素不存在,需要添加键值对
    dictionary->items[dictionary->count].key = malloc(dictionary->size); // 为键分配内存
    memcpy(dictionary->items[dictionary->count].key, key, dictionary->size); // 复制键的数据
    dictionary->items[dictionary->count].value = value; // 存储值
    dictionary->count++; // 元素数量加 1
}

// 从泛型字典中获取一个值
void *Dictionary_Get(Dictionary *dictionary, void *key) {
    
    
    // 计算键的哈希值
    unsigned int hash = Dictionary_HashFunction(dictionary, key);
    // 查找哈希值对应的元素
    for (size_t i = 0; i < dictionary->count; i++) {
    
    
        if (dictionary->items[i].key != NULL && memcmp(dictionary->items[i].key, key, dictionary->size) == 0) {
    
    
            return dictionary->items[i].value; // 返回值
        }
    }
    // 如果哈希值对应的元素不存在,返回 NULL
    return NULL;
}

// 从泛型字典中移除一个键值对
void Dictionary_Remove(Dictionary *dictionary, void *key) {
    
    
    // 计算键的哈希值
    unsigned int hash = Dictionary_HashFunction(dictionary, key);
    // 查找哈希值对应的元素
    for (size_t i = 0; i < dictionary->count; i++) {
    
    
        if (dictionary->items[i].key != NULL && memcmp(dictionary->items[i].key, key, dictionary->size) == 0) {
    
    
            // 释放键的内存
            free(dictionary->items[i].key);
            // 将字典中的元素向前移动
            for (size_t j = i; j < dictionary->count - 1; j++) {
    
    
                dictionary->items[j] = dictionary->items[j + 1];
            }
            dictionary->count--; // 元素数量减 1
            return;
        }
    }
}

// 销毁一个泛型字典
void Dictionary_Destroy(Dictionary *dictionary) {
    
    
    // 释放字典中的键的内存
    for (size_t i = 0; i < dictionary->count; i++) {
    
    
        free(dictionary->items[i].key);
    }
    // 释放字典元素的内存
    free(dictionary->items);
    // 释放字典结构体的内存
    free(dictionary);
}

int main() {
    
    
    // 初始化一个存储 int 类型的键和 char * 类型的值的泛型字典
    Dictionary *dictionary = Dictionary_Init(sizeof(int));
    // 向字典中添加键值对
    int a = 1, b = 2, c = 3;
    char *x = "hello", *y = "world", *z = "dictionary";
    Dictionary_Add(dictionary, &a, x);
    Dictionary_Add(dictionary, &b, y);
    Dictionary_Add(dictionary, &c, z);
    // 从字典中获取值
    char *p = Dictionary_Get(dictionary, &b);
    printf("%s\n", p); // 输出 world
    // 从字典中移除键值对
    Dictionary_Remove(dictionary, &b);
    // 销毁字典
    Dictionary_Destroy(dictionary);
    return 0;
}

希望这个示例代码能帮助你理解如何用 C 语言实现一个泛型字典。

猜你喜欢

转载自blog.csdn.net/phker/article/details/131232124