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

来源:互联网 发布:厦门大学网络教育报名 编辑:程序博客网 时间:2024/06/05 04:38

今天学习了一下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;    }};


原创粉丝点击