假设您有一个包含以下字符串的文件
a a a b a a b a a b b a b
您无权访问该文件,但只能访问一次提供一个字符的函数FetchNextChar()。
并且匹配的模式是a a b
你如何计算总点击次数?
这就是我的想法。
所以在第一次获取后我们有
Pattern -a
Queue - a
Then
Pattern -a a
Queue[0] a->a
Queue[1] a
3rd
Pattern a a b
Queue[0] a -->a--> a //doesn't match, dequeue
Queue[1] a-> a
Queue[2] a
我认为这会有效,但我看到的问题是,如果有多个字符与模式的第一个字符匹配,我将不断添加到队列中,因此继续增加列表。
有什么想法吗?
答案 0 :(得分:3)
您可以使用基于状态的算法:
我们可以看到,每次读取'b'
时,我们都会继续state=0
,如果我们在state=2
上,则模式发生次数会增加1。当读取'a'
时,我们会明确转到state=2
所界定的下一个状态。
这是一个实现算法的python脚本
stream = ['a','a','a','b','a','a','b','a','a','b','b','a','b']
state = 0
nbMatch = 0
for c in stream:
if c=='a':
if state==0 or state==1:
state = state+1
#if state == 2: state=2
else: #c=='b'
if state==2:
nbMatch = nbMatch+1
state = 0
print c, " state=", state
print nbMatch
答案 1 :(得分:2)
使用Rabin–Karp algorithm计算滑动窗口的rolling hash
可以有效地解决这个问题,一个简单的滚动哈希函数是对字符的ASCII码求和,但是你可以使用这个{{1}数组1}}为了减少碰撞,我测试了这些素数,并在一个大而相似的字符串和模式匹配上给了我一些碰撞:
primes
以下是上述算法的伪代码,用于打印匹配计数:
primes[] = {13 , 7963 , 17443 , 27527 , 37879 , 48673 , 59407 , 70729 , 81883 , 93251 , 104789 , 116531 , 128239 , 139969 , 151783 , 163883 , 176159 , 188029 , 200257 , 212447 , 224831 , 237283 , 249517 , 262217 , 274661 , 287173};