【问题标题】:Find one occurence of substring using suffix array使用后缀数组查找出现的子字符串
【发布时间】:2014-12-22 09:38:40
【问题描述】:

我正在尝试找出如何在 后缀数组 中进行 二分搜索 以查找一次模式的出现。 让我们发一条短信:petertomasjohnerrnoerror。 我试着找er

SA是这个文本的后缀数组:8,14,19,3,1,12,10,7,13,17,18,11,6,22,0,23,16,21,15,20,4,9,2,5

现在,我想找到后缀数组的任何索引,它的值指向一个'er'。所以输出将是 SA 中指向 3,14 or 19 的索引,因此它将返回 1,2 或 3

我正在尝试使用二分搜索,但我不知道如何使用。

def findOneOccurence(text,SA,p):
    high = len(text)-1           # The last index
    low = 0                      # the lowest index
    while True:
        check = (high-low)/2     # find a middle

        if p in text[SA[check]:SA[check]+len(p)]:
            return check
        else:
            if text[SA[check]:SA[check]+len(p)]<p:
                low = check
            else:
                high = check
        if high<=low:
            return None

这将返回11。但是text[SA[11]:SA[11]+2]'oh' instad 的'er'。 问题可能出在哪里?

此功能适用于大约数百万个字符的大型文本。

编辑:我发现了一个错误。而不是如果text[SA[check]:SA[check+len(p)]]&lt;p: 应该是text[SA[check]:SA[check]+len(p)]&lt;p: 但它仍然是错误的。它返回 None 而不是 'er'

编辑二:另一个错误:如果 high>=low 更改为 high

编辑 III:现在它可以工作了,但是在某些输入上它会进入循环并且永远不会结束。

【问题讨论】:

  • 你把reer搞混了吗?
  • @是的,我的意思是“er”,因为文本中没有“re”,谢谢
  • 我认为您没有找到正确的方法。不应该是(high+low)/2 而不是(high-low)/2
  • 谢谢,这是另一个错误。快完成了:)
  • 你应该使用 in 而不是 ==

标签: python list search binary-search suffix-array


【解决方案1】:

借阅编辑https://hg.python.org/cpython/file/2.7/Lib/bisect.py

>>> text= 'petertomasjohnerrnoerror'
>>> SA = 8,14,19,3,1,12,10,7,13,17,18,11,6,22,0,23,16,21,15,20,4,9,2,5
>>> def bisect_left(a, x, text, lo=0, hi=None):
    if lo < 0:
        raise ValueError('lo must be non-negative')
    if hi is None:
        hi = len(a)
    while lo < hi:
        mid = (lo+hi)//2
        if text[a[mid]:] < x: lo = mid+1
        else: hi = mid
    if not text[a[lo]:].startswith(x): 
        # i suppose text[a[lo]:a[lo]+len(x)] == x could be a faster check
        raise IndexError('not found')
    return a[lo]

>>> bisect_left(SA, 'er', text)
14

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 2013-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-24
    • 2015-12-31
    • 1970-01-01
    相关资源
    最近更新 更多