#coding: utf-8 ''' mbinary ######################################################################### # File : rabin_karp.py # Author: mbinary # Mail: zhuheqin1@gmail.com # Blog: https://mbinary.xyz # Github: https://github.com/mbinary # Created Time: 2018-12-11 00:01 # Description: rabin-karp algorithm ######################################################################### ''' def isPrime(x): for i in range(2,int(x**0.5)+1): if x%i==0:return False return True def getPrime(x): '''return a prime which is bigger than x''' for i in range(x,2*x): if isPrime(i):return i def findAll(s,p): '''s: string p: pattern''' dic={} n,m = len(s),len(p) d=0 #radix for c in s: if c not in dic: dic[c]=d d+=1 sm = 0 for c in p: if c not in dic:return [] sm = sm*d+dic[c] ret = [] cur = 0 for i in range(m): cur=cur*d + dic[s[i]] if cur==sm:ret.append(0) tmp = n-m q = getPrime(m) cur = cur%q sm = sm%q exp = d**(m-1) % q for i in range(m,n): cur = ((cur-dic[s[i-m]]*exp)*d+dic[s[i]]) % q if cur == sm and p==s[i-m+1:i+1]: ret.append(i-m+1) return ret def randStr(n=3): return [randint(ord('a'),ord('z')) for i in range(n)] if __name__ =='__main__': from random import randint s = randStr(50) p = randStr(1) print(s) print(p) print(findAll(s,p))