Python Boyer-moore算法-计算所有匹配子串

Python Boyer-moore算法-计算所有匹配子串,python,boyer-moore,Python,Boyer Moore,我正在用python实现boyer-moore算法,我需要计算子字符串在字符串中出现的次数 我的字符串存储在向量中: string = ['A', 'B', 'B', 'C', 'F', 'D', 'B', 'B'] needle = ['B', 'B'] 指针也是一个向量: string = ['A', 'B', 'B', 'C', 'F', 'D', 'B', 'B'] needle = ['B', 'B'] 我的问题是: 我实现的算法只是返回指针第一次出现的索引。 在上面的示例中,

我正在用python实现boyer-moore算法,我需要计算子字符串在字符串中出现的次数

我的字符串存储在向量中:

string = ['A', 'B', 'B', 'C', 'F', 'D', 'B', 'B']
needle = ['B', 'B']
指针也是一个向量:

string = ['A', 'B', 'B', 'C', 'F', 'D', 'B', 'B']
needle = ['B', 'B']
我的问题是:

我实现的算法只是返回指针第一次出现的索引。 在上面的示例中,它返回
1
,但是,正如我前面所说的,我需要每次计算指针是否出现在数组中,并期望它返回2

示例和预期回报

1

haystack = ['A', 'B', 'B', 'C', 'F', 'D', 'B', 'B']
needle = ['B', 'B'] 
expected return = 2
2

haystack = ['A', 'F', 'T', 'C', 'B', 'F', 'T', 'a', 'F', 'T']
needles = ['F', 'T']
expected return = 3
我的代码i 在
搜索
功能中,我尝试更改
返回i
(索引),使用
计数器+=1
,以计数匹配的针,但是,如果我这样做,它会给我以下错误:

Traceback (most recent call last):
  File "booyer-moore.py", line 103, in <module>
    main(files)
  File "booyer-moore.py", line 98, in main
    index = search(haystack, needle)
  File "booyer-moore.py", line 18, in search
    i += max(offset_table[len(needle) - 1 - j], character_table.get(haystack[i]))
IndexError: list index out of range

回溯(最近一次呼叫最后一次):
文件“booyer moore.py”,第103行,在
主要(文件)
文件“booyer moore.py”,第98行,在main中
索引=搜索(草堆、针)
文件“booyer moore.py”,第18行,正在搜索中
i+=max(偏移量表[len(针)-1-j],字符表.get(haystack[i]))
索引器:列表索引超出范围
def搜索(草堆、针):
计数器=0
如果len(指针)==0:
返回0
character\u table=createCharacterTable(指针)
偏移量表=createOffsetTable(指针)
i=透镜(针)-1
而我(干草堆):
j=透镜(针)-1
而针[j]==草堆[i]:
如果j==0:
返回i
#计数器+=1
i-=1
j-=1
i+=max(偏移量表[len(针)-1-j],字符表.get(haystack[i]))
返回计数器
def createCharacterTable(指针):
表={}
对于范围内的i(透镜(针)-1):
表[针[i]]=透镜(针)-1-i
返回表
def CreateOffsetable(指针):
表=[]
lastPrefixPosition=len(针)
对于反向(范围(透镜(针)))中的i:
如果isPrefix(针,i+1):
lastPrefixPosition=i+1
表.追加(lastPrefixPosition-i+len(针)+1)
对于范围内的i(透镜(针)-1):
slen=足够长度(针,i)
表[slen]=透镜(针)-1-i+slen
返回表
def isPrefix(打捆针,位置):
j=0
对于范围内的i(位置,透镜(针)):
如果针[i]!=针[j]:
返回错误
j+=1
返回真值
def足够长度(打捆针,位置):
长度=0
j=透镜(针)-1
对于反向(范围(位置+1))中的i:
如果针[i]==针[j]:
长度+=1
其他:
打破
j-=1
返回长度

不确定之后是否符合
max
,但我想您应该将
I
重置为启动时的值(如果您的针大小为2,则
I-=1
发生一次),更新计数器,然后断开:

        if j == 0:
            i += len(needle) - 1
            counter += 1
            break
        i -= 1
        j -= 1

我发现了几个错误,我已经在你的解决方案中纠正了这些错误

def search(haystack, needle):
    if len(needle) == 0:
        return 0
    character_table = createCharacterTable(needle)
    offset_table = createOffsetTable(needle)
    i = len(needle) - 1
    while i < len(haystack):
        j = len(needle) - 1
        while needle[j] == haystack[i]:
            if j == 0:
                yield i
                break
            i -= 1
            j -= 1
        if(character_table.get(haystack[i])):
            i += max(character_table.get(haystack[i]),offset_table[len(needle) - 1 - j])
        else:
            i += offset_table[len(needle) - 1 - j]

haystack = ['A', 'F', 'T', 'C', 'B', 'F', 'T', 'a', 'F', 'T']
needle = ['F', 'T']
generator=search(haystack,needle)
for i in generator:
    print("Result: "+str(i))
由此产生的结果

Result: 1
Result: 5
现在我打印了你的胶版纸,它给了我[1,5],我觉得不太合适。在执行期间打印i和j的值,我得到:

{'F': 1} [1, 5]
j is 1
i is 2
Result: 1
j is 0
i is 6
Result: 5
j is 0
i is 10

所以在索引6和10之间有一个跳跃。你能解释一下你的抵销表的逻辑吗?如果我能找出逻辑中的任何错误,我会更新这个答案。

我用这个干草堆试过:
haystack=['A',C',B','B','B','B','B','B','B','B','B']
和这个针:
针=['B','B']
,它给了我
2
作为答案,真的,我想你应该对@Axxelerated答案做出反应,并找到解决问题的方法。