【发布时间】:2017-11-06 06:24:20
【问题描述】:
我需要找到一个字节对象 s1 的最大前缀(从开头开始的字节串),它是另一个字节对象 s2 的子字符串,并返回 s2 中的起始位置和长度。在这种情况下,s2 也恰好与 s1 重叠。
最佳结果是距离 s2 结尾最近的最长前缀。
我尝试使用下面的 bytes.rfind 方法来实现这一点。
注意:这是试图在字节对象src 中从索引index 开始查找最大前缀,该前缀在src 中较早出现在index 之前的最大maxOffset 字节内。因此,s1 是src[index:],s2 是src[index-maxOffset:index+maxLength-1]。 maxLength 是我有兴趣搜索的前缀的最大长度。
def crl(index, src, maxOffset, maxLength):
"""
Returns starting position in source before index from where the max runlength is detected.
"""
src_size = len(src)
if index > src_size:
return (-1, 0)
if (index+maxLength) > src_size:
maxLength = src_size - index
startPos = max(0, index-maxOffset)
endPos = index+maxLength-1
l = maxLength
while l>1:
if src[index:index+l] in src[startPos:index+l-1]:
p = src.rfind(src[index:index+l], startPos, index+l-1)
return (p,l)
l -= 1
return (-1, 0)
由于之前的实现非常慢,我也尝试如下手动编码
def ocrl(index, src, maxOffset, maxLength):
"""
Returns starting position in source before index from where the max runlength is detected.
"""
size = len(src)
if index>=size:
return (-1, 0)
startPos = index - 1 # max(0, index-maxOffset)
stopPos = max(0, index-maxOffset)
runs = {}
while(startPos >= stopPos):
currRun = 0
pos = startPos
while src[pos] == src[index+currRun]:
currRun += 1
pos += 1
if currRun == maxLength:
return (startPos, maxLength) #found best possible run
if (pos >= size) or ((index+currRun) >= size):
break
if (currRun > 0) and (currRun not in runs.keys()):
runs[currRun] = startPos
startPos -= 1
if not runs:
return (-1, 0)
else:
# Return the index from where the longest run was found
return (runs[max(runs.keys())], max(runs.keys()))
虽然第二次实现速度更快,但它仍然很慢,而且我认为效率低下。我怎样才能使它更高效并运行得更快?
【问题讨论】:
-
os.path.commonprefix能让你的函数更快吗? -
如果字符串的字节值超出可打印的 ascii 范围,
os.path.commonprefix是否重要?它会像'.'这样对待字符吗?或 '/' 以特殊方式? -
我没有看到任何 in the sources 会在这些问题上给您带来任何麻烦。
标签: python string algorithm search