知识总结
C语言库uthash常用库函数以及LeetCode例题(多数元素)_uthash.h-CSDN博客
C语言哈希表uthash的使用方法详解(附下载链接)_uthash.h下载-CSDN博客
例题:同构字符串
题目描述
给定两个字符串 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;
}