rabin-karp 算法学习心得-lintcode 594

今天学习了一下rabin-karp算法,可以说是kmp的简易版,但是效果是差不多的

这题在lintcode594上看着九章算法的视频学会的


说一下rabin-karp的核心思想,用到了hashtable,就是将一个具体的string的key转换成了一个int类型 value

key是唯一的,但是value不一定唯一,所以我们可以通过对大数取模的方法降低value重复的概率

具体来看一个source=abcde,target=bcd

要求我们在source中找到target首次出现的位置


首先要明确的是,如何将一个string映射到一个value值

这里采用的方法如下:

abc= (a*31^2+b*31^1+c*31^0)%1000000

31这个数字是一般经验

这个数可能会过大,所以需要一个大数取模

所以我们将target字符串的 hashvalue计算出来

然后在source中每次取长度为3的字串计算出value值进行一个对比

如果某一个字串的value值和target的value值相等

这里注意,还需要比较一下substr和target是否相等,因为可能value重复尽管已经进行大数取模了


具体可以参考以下代码

class Solution {
public:
    int base=100000;
    /**
     * @param source a source string
     * @param target a target string
     * @return an integer as index
     */
    int strStr2(const char* source, const char* target) {
        // Write your code here
        if(source==NULL||target==NULL)
            return -1;
        string strsource=source;
        string strtarget=target;
        int m=strtarget.size();
        if(m==0)
            return 0;
        int m_code=1;
        for(int i=0;i<m;i++)
        {
            m_code=(m_code*31)%base;
        }
        int targetcode=0;
        for(int i=0;i<m;i++)
        {
            targetcode=(targetcode*31+strtarget[i])%base;
        }
        int hashcode=0;
        for(int i=0;i<strsource.size();i++)
        {
            hashcode=(hashcode*31+strsource[i])%base;
            if(i<m-1)
                continue;
            if(i>=m)
            {
                hashcode=hashcode-(strsource[i-m]*m_code)%base;
                if(hashcode<0)
                    hashcode+=base;
            }
            if(hashcode==targetcode&&strsource.substr(i-m+1,m)==strtarget)
            {
                return i-m+1;
            }
        }
        return -1;
    }
};


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值