【C语言】uthash 哈希表专题

知识总结

C语言库uthash常用库函数以及LeetCode例题(多数元素)_uthash.h-CSDN博客

C语言uthash总结_uthash.h-CSDN博客

C语言哈希表uthash的使用方法详解(附下载链接)_uthash.h下载-CSDN博客

例题:同构字符串

205. 同构字符串 - 力扣(LeetCode)

题目描述

给定两个字符串 s 和 t ,判断它们是否是同构的。

如果 s 中的字符可以按某种映射关系替换得到 t ,那么这两个字符串是同构的。

每个出现的字符都应当映射到另一个字符,同时不改变字符的顺序。不同字符不能映射到同一个字符上,相同字符只能映射到同一个字符上,字符可以映射到自己本身。

解题思路

输入两个字符串 s 和 t,判断是否同构。需要维护两张哈希表,哈希表 s2t 以字符串 s 中的字符为键,以字符串 t 中的字符为值,哈希表 t2s 以字符串 t 中的字符为键,以字符串 s 中的字符为值。

例一:s = "egg", t = "add"

遍历哈希表 s2t ,若不存在以 'e' 为键的项,则添加;若已存在以 'e' 为键的项,判断该项的值是否等于 'a',等于 'a' 则继续遍历,不等于 'a' 则返回 false。

遍历哈希表 t2s ,若不存在以 'a' 为键的项,则添加;若已存在以 'a' 为键的项,判断该项的值是否等于 'e',等于 'e' 则继续遍历,不等于 'e' 则返回 false。

例二:s = "foo", t = "bar"

遍历哈希表 s2t ,在哈希表中添加 o -> a 的映射(以 'o' 为键,'a' 为值的元素项),继续遍历时发现 'o' 还映射到 'r',不满足一对一映射的条件,返回 false。

哈希函数

需要用到两个哈希函数:

添加元素:HASH_ADD

查找元素:HASH_FIND

HASH_ADD(hh_name, head, keyfield_name, key_len, item_ptr)  //表示添加的键值可以是任意类型
HASH_ADD_STR(head, keyfield_name, item_ptr)  //表示添加的键值为字符串类型
HASH_ADD_INT(head, keyfield_name, item_ptr)  //表示添加的键值为int类型
HASH_ADD_PTR(head, keyfield_name, item_ptr)  //表示添加的键值为指针类型

HASH_FIND(hh_name, head, key_ptr, key_len, item_ptr)  //表示添加的键值可以是任意类型
HASH_FIND_STR(head, key_ptr, item_ptr)  //表示添加的键值为字符串类型
HASH_FIND_INT(head, key_ptr, item_ptr)  //表示添加的键值为int类型
HASH_FIND_PTR(head, key_ptr, item_ptr)  //表示添加的键值为指针类型

hh_name:UT_hash_handle结构中字段的名称,俗称 hh。

head:结构指针变量,用作哈希的“头”。如此命名是因为它最初指向添加到哈希中的第一项。

keyfield_name:结构中键字段的名称。(对于多字段键,这是键的第一个字段)。如果您不熟悉宏,则将字段名称作为参数传递似乎很奇怪。请参阅注释。

key_len:键字段的长度(以字节为单位)。例如,对于整数键,它是sizeof(int),而对于字符串键,它是strlen(key)。

key_ptr:对于HASH_FIND,这是指向要在哈希中查找的键的指针(由于它是指针,因此您不能在此处直接传递文字值)。对于 HASH_ADD_KEYPTR,这是要添加的项的键的地址。

item_ptr:指向要添加,删除,替换或查找的结构的指针,或迭代期间的当前指针。这是一个输入参数HASH_ADD, HASH_DELETE和HASH_REPLACE宏,和用于输出参数HASH_FIND 和HASH_ITER。(当HASH_ITER用于迭代时,tmp_item_ptr 是与item_ptr内部使用的类型相同的另一个变量)。

注:在 HASH_ADD 函数中,item_ptr 指向被添加的项,先对 item_ptr 赋值,再添加到哈希表中;在 HASH_FIND 函数中,item_ptr 指向函数返回的值,在调用 HASH_FIND 前将 item_ptr 置为NULL,若未能在哈希中找到,item_ptr 指向 NULL,若能找到,item_ptr 指向对应的项。

代码

struct HashTable{
    char key;
    char val;
    UT_hash_handle hh;
};

bool isIsomorphic(char* s, char* t) {
    struct HashTable* s2t = NULL;
    struct HashTable* t2s = NULL;
    int len = strlen(s);
    for(int i = 0; i < len; i++){
        char x = s[i];
        char y = t[i];
        struct HashTable* p1 = NULL;
        struct HashTable* p2 = NULL;
        HASH_FIND(hh, s2t, &x, sizeof(char), p1);
        HASH_FIND(hh, t2s, &y, sizeof(char), p2);

        if(p1){
            if(p1->val != y){
                return false;
            }
        }else{
            p1 = (struct HashTable*)malloc(sizeof *p1); // sizeof(struct HashTable)
            p1->key = x;
            p1->val = y;
            HASH_ADD(hh, s2t, key, sizeof(char), p1);
        }

        if(p2){
            if(p2->val != x){
                return false;
            }
        }else{
            p2 = (struct HashTable*)malloc(sizeof *p2);
            p2->key = y;
            p2->val = x;
            HASH_ADD(hh, t2s, key, sizeof(char), p2);
        }
    }
    return true;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值