Horner法则,MurMurHash

项目github地址:bitcarmanlee easy-algorithm-interview-and-practice
欢迎大家star,留言,一起学习进步

1.Horner法则

假设有一个n次多项式需要计算。
f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 f(x) = a_nx^n + a_{n-1}x^{n-1} + \cdots + a_1x + a_0 f(x)=anxn+an1xn1++a1x+a0
如果直接进行计算,需要 n ( n + 1 ) 2 \frac{n(n+1)}{2} 2n(n+1)次乘法与 n n n次加法。而乘法的代价是比较大的,所以效率会比较低。

将上面的多项式改写一下

f ( x ) = a n x n + a n − 1 x n − 1 + ⋯ + a 1 x + a 0 = ( a n x n − 1 + a n − 1 x n − 2 + ⋯ + a 2 x + a 1 ) x + a 0 = ( ( ( a n x + a n − 1 ) x + a n − 2 ) x + ⋯ + a 1 ) x + a 0 \begin{aligned} f(x) & = a_nx^n + a_{n-1}x^{n-1} + \cdots + a_1x + a_0 \\ & = (a_nx^{n-1} + a_{n-1}x^{n-2} + \cdots + a_2x + a_1)x + a_0 \\ & = (((a_nx + a_{n-1})x + a_{n-2})x + \cdots + a_1)x + a_0\\ \end{aligned} f(x)=anxn+an1xn1++a1x+a0=(anxn1+an1xn2++a2x+a1)x+a0=(((anx+an1)x+an2)x++a1)x+a0
求上面的值的时候,很明显可以从括号里由内到位一次计算,最后的计算复杂度为n次乘法与n次加法。

2.java String中的HashCode

看看String类里hashCode的源码。

    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

根据源码不难看出,其计算方式就是
s [ 0 ] ∗ 3 1 ( n − 1 ) + s [ 1 ] ∗ 3 1 ( n − 2 ) + . . . + s [ n − 2 ] ∗ 31 + s [ n − 1 ] s[0]*31^{(n-1)} + s[1]*31^{(n-2)} + ... + s[n-2] * 31 + s[n-1] s[0]31(n1)+s[1]31(n2)+...+s[n2]31+s[n1]

3.MurMurHash

上面的hashCode方法有个不好的地方就是变化不够激烈。比如我们看一下的例子

    @Test
    public void test2() {
        String s1 = "abcdefg";
        String s2 = "abcdeff";
        System.out.println(s1.hashCode());
        System.out.println(s2.hashCode());
    }

上面代码运行的结果为

-1206291356
-1206291357

两个相似的字符串,得到的hash值也很相似。

MurmurHash 是一种非加密型哈希函数,适用于一般的哈希检索操作。由Austin Appleby 在2008年发明,并出现了多个变种,都已经发布到了公有领域。与其它流行的哈希函数相比,对于规律性较强的key,MurmurHash的随机分布特征表现更良好,现在在libstdc++,hadoop和nginx等很多著名开源项目中使用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值