• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
neverlandly
博客园    首页    新随笔    联系   管理    订阅  订阅

Lintcode: Hash Function && Summary: Modular Multiplication, Addition, Power && Summary: 长整形long

In data structure Hash, hash function is used to convert a string(or any other type) into an integer smaller than hash size and bigger or equal to zero. The objective of designing a hash function is to "hash" the key as unreasonable as possible. A good hash function can avoid collision as less as possible. A widely used hash function algorithm is using a magic number 33, consider any string as a 33 based big integer like follow:

hashcode("abcd") = (ascii(a) * 33^3 + ascii(b) * 33^2 + ascii(c) *33 + ascii(d)) % HASH_SIZE 

                              = (97* 33^3 + 98 * 33^2 + 99 * 33 +100) % HASH_SIZE

                              = 3595978 % HASH_SIZE

here HASH_SIZE is the capacity of the hash table (you can assume a hash table is like an array with index 0 ~ HASH_SIZE-1).

Given a string as a key and the size of hash table, return the hash value of this key.f



Example
For key="abcd" and size=100, return 78

Clarification
For this problem, you are not necessary to design your own hash algorithm or consider any collision issue, you just need to implement the algorithm as described.

对于overflow要特别小心,即便是intermediate result,也要小心overflow

跟Fast Power那道题类似,modular multiplication addition的证明在此

    • (a + b) % p = (a % p + b % p) % p (1)
    • (a - b) % p = (a % p - b % p) % p (2)
    • (a * b) % p = (a % p * b % p) % p (3)
    • a ^ b % p = ((a % p)^b) % p (4)
 1 class Solution {
 2     /**
 3      * @param key: A String you should hash
 4      * @param HASH_SIZE: An integer
 5      * @return an integer
 6      */
 7     public int hashCode(char[] key,int HASH_SIZE) {
 8         if (key.length == 0) return 0;
 9         int result = 0;
10         int base = 1;
11         for (int i=key.length-1; i>=0; i--) {
12             int num = (int)(key[i] - '\0');
13             result += modMultiply(num, base, HASH_SIZE);
14             result = result % HASH_SIZE;
15             base = modMultiply(base, 33, HASH_SIZE);
16         }
17         return result % HASH_SIZE;
18     }
19     
20     public int modMultiply(int a, int b, int c) {
21         long temp = (long)a * b;
22         return (int)(temp % c);
23     }
24 };

15行如果如果每次都 base *= 33,即使把base 定义为long型,String一长也会溢出的; 我又试了用Math.pow(33, i), 一样overflow。说明强行算33的power还是不行的,是会溢出的。还是要用Modular Multiplication

(A * B) mod C, 需要注意的是,A、B、C都定义为int,A*B要小心overflow, 所以用long来存这个乘积,然后mod C之后再把结果存成int型

第21行,如果是就是错的:a * b已经overflow了

1 public int modMultiply(int a, int b, int c) {
2          long temp = a * b;
3          return (int)(temp % c);
4      }
5 };

处理方法可以是:long temp = (long) a * b;  或者a和b都定义为long型然后long temp = a * b

 

方法二:不用long type, 网上别人的做法,没看懂

 1     public int hashCode(char[] key,int HASH_SIZE) {
 2         int result = 0;
 3         for (int i = 0; i < key.length; i++) {
 4             result = helper(result, 33, HASH_SIZE);
 5             result += key[i];
 6             result %= HASH_SIZE;
 7         }
 8         return result;
 9     }
10 
11     int helper(int num, int base, int mod) {
12         int result = 0;
13         int temp = num - mod;
14         for (int i = 0; i < base; i++) {
15             if (result + temp > 0) {
16                 result += temp;
17             } else {
18                 result += num;
19             }
20         }
21         return result;
22     }

 

posted @ 2015-02-07 07:06  neverlandly  阅读(1765)  评论(1)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3