散列:

将元素通过一个函数转换为整数,使得该整数可以尽量唯一地代表这个元素。

散列函数:

一般直接用STL中的map或unordered_map,除非必须模拟这些方法或者对算法效率要求较高,否则不需要自己实现解决冲突的方法

①直接定址法

  • 恒等变换:将 key(输入的数) 作为数组下标 ⭐——最常见最实用
  • 线性变换:H(key) = a * key + b

②平方取中法

  • 取 key 平方的中间若干位作为 hash 值(很少用)

③除留取余法

  • H(key) = key % mod (表长Tsize >= mod,否则会越界)
1、开放定址法
  • 线性探查法:H(key), H(key)+1, …
  • 平方探查法:H(key), H(key)+1^2, H(key)-1^2, H(key)+2^2, H(key)-2^2, …
    if (H(key) + k^2 > Tsize) H(key)+k^2 % Tsize
    if (H(key) - k^2 < 0) ((H(key) - k^2) % Tsize + Tsize) % Tsize (可只正向探查避免此种麻烦)
2、链地址法

字符串hash:

将一个字符串S映射为一个整数,使得整数可以尽可能唯一地代表字符串S
(1) 字符串由大写字母 A-Z 组成
  • 将大写字母 A-Z 视为 0-25,即对应到了26进制中,再转换为10进制。转换为的整数最大为26^len-1,len为字符串长度
int hashFunc(char S[], int len){
   
    int id = 0;
    for (int i = 0; i < len; i++){
   
        id = id * 26 + (S[i] - 'A');
    }
    return id;
}
(2) 字符串由大写字母 A-Z 和小写字母 a-z 组成
  • 52进制转10进制问题
(3) 字符串由大写字母 A-Z,小写字母 a-z 和 数字 1-9 组成
  • (1) 62进制转10进制问题
  • (2) 若保证字符串末尾是确定个数的数字,可将前面英文字母部分转换为整数后将数字拼接上去
int hashFunc(char S[], int len){
   
    int id = 0;
    for (int i = 0; i < len - 1; i++){
   
        id = id * 26 + (S[i] - 'A');
    }
    id = id * 10 + (S[len-1] - '0');
    return id;
}

1002 A+B for Polynomials (25分)

1092 To Buy or Not to Buy (20)

1116 Come on! Let’s C (20)

1121 Damn Single (25)

1009 Product of Polynomials (25)(未做)

1084 Broken Keyboard (20) (未做)