1、DJB2 哈希函数
著名的哈希算法之一,由 Daniel J. Bernstein 提出,具有较好的性能和广泛的应用。它简单且效果不错。
#include <stdio.h> unsigned long hash(unsigned char *str) { unsigned long hash = 5381; int c; while ((c = *str++)) { hash = ((hash << 5) + hash) + c; // hash * 33 + c } return hash; } int main() { char *str = "Hello, World!"; printf("Hash value: %lu\n", hash((unsigned char *)str)); return 0; }
2、SDBM 哈希函数
SDBM 哈希函数是另一种常见的字符串哈希算法,简单并且执行效率高。
#include <stdio.h> unsigned long sdbm_hash(unsigned char *str) { unsigned long hash = 0; int c; while ((c = *str++)) { hash = c + (hash << 6) + (hash << 16) - hash; } return hash; } int main() { char *str = "Hello, World!"; printf("SDBM Hash value: %lu\n", sdbm_hash((unsigned char *)str)); return 0; }
3、FNV-1a 哈希函数
FNV-1a 是一个简单的哈希算法,使用异或和乘法操作来计算哈希值,效率高并且结果均匀。
#include <stdio.h> unsigned long fnv1a_hash(unsigned char *str) { unsigned long hash = 14695981039346656037UL; int c; while ((c = *str++)) { hash ^= c; hash *= 1099511628211; } return hash; } int main() { char *str = "Hello, World!"; printf("FNV-1a Hash value: %lu\n", fnv1a_hash((unsigned char *)str)); return 0; }
4、BKDR Hash(倍数种子法)
经典中国算法竞赛中常用的字符串哈希函数,选择合适的 seed 可降低碰撞率。
#include <stdio.h> // 哈希函数定义(BKDR Hash) unsigned int hash4(const char *str) { unsigned int seed = 131; // 常用:31、131、1313 等 unsigned int hash = 0; while (*str) hash = hash * seed + (unsigned char)(*str++); return hash; } int main() { const char *examples[] = { "hello", "world", "hash", "function", "hello" // 重复测试 }; int n = sizeof(examples) / sizeof(examples[0]); for (int i = 0; i < n; i++) { printf("String: %-10s Hash: %u\n", examples[i], hash4(examples[i])); } return 0; }
5、简单加权求和法(乘 31)
最常见的哈希方法,类似 Java 的 String.hashCode(
) 实现。
#include <stdio.h> // 哈希函数定义(乘31法) unsigned int hash1(const char *str) { unsigned int hash = 0; while (*str) hash = hash * 31 + (unsigned char)(*str++); return hash; } int main() { const char *examples[] = { "apple", "banana", "cherry", "apple", // 相同字符串 "banana", // 相同字符串 "Apple" // 大小写不同 }; int n = sizeof(examples) / sizeof(examples[0]); for (int i = 0; i < n; i++) { printf("String: %-10s Hash: %u\n", examples[i], hash1(examples[i])); } return 0; }