如何用最短到最长的匹配从头到尾替换文本
我有数据:
In [1807]: text='110011111000011010110011'
和一个看起来像这样的字典:
s={'11': '++--', '01': '-+-+-', '000': '+-++++++', '001': '--', '100': '--+-', '101': '----++-+--'}
我想将文本的输出替换为
'++----++--++--+-++++++-+-+-----++-+---+-+---+-++--'
所以第一个 11,变为++--,第二个匹配是 001,然后是 --,第三个匹配是 11,然后被++-- 替换。最短的匹配项首先替换,但如果未找到,则替换第二长的匹配项。这必须从字符串的开头开始迭代,否则它不起作用。我正在寻找解决此问题的惯用方法。
我使用的当前代码有效,但我认为有更惯用的方法来解决这个问题。这是我目前拥有的:
s={'11': '++--', '01': '-+-+-', '000': '+-++++++', '001': '--', '100': '--+-', '101': '----++-+--'}
peekstart=0
peekend=1
sptr='110011111000011010110011'
bytestr=b''
while peekstart+peekend <= sptrlen:
match=False
while match == False:
peek = sptr[peekstart:peekstart+peekend]
findptr = s.get(peek)
while findptr == None:
peek = sptr[peekstart:peekstart+peekend+stream]
stream=stream+1
findptr = s.get(peek)
if stream == 0:
peekstart=peekstart+peekend+stream
else:
peekstart=peekstart+peekend+stream-1
stream=0
bytestr+=s.get(peek).encode()
match = True
print(bytestr)
b'++----++--++--+-++++++-+-+-----++-+---+-+---+-++--'
有没有更惯用的方法来解决这个问题?
已回答
使用这里的答案,我想出了这个新版本,它可以很好地解压缩,并且不需要为以零开头的二进制文件提供缓冲区:
from functools import reduce
s={'11': '++--', '01': '-+-+-', '000': '+-++++++', '001': '--', '100': '--+-', '101': '----++-+--'}
def decompressHuffmanCode(a, bit):
return ('', a[1] + a[2][a[0]+bit[0]], a[2]) if (a[0]+bit[0] in a[2]) else (a[0]+bit[0], a[1], a[2])
# Added one to the front to deal with cases of the binary starting with zeroes
compressed_binary='1110011111000011010110011'
read_compressed_binary = compressed_binary[1:]
remainder,bytestr,s = reduce(decompressHuffmanCode, read_compressed_binary, ('', '', s))
print(bytestr)
感谢大家的回复,才有了这个精简版
请您参考如下方法:
这是一个常见的 eat-function。你从左边吃,直到你找到字典中匹配的东西。
text='110011111000011010110011'
s={'11': '++--', '01': '-+-+-', '000': '+-++++++', '001': '--', '100': '--+-', '101': '----++-+--'}
string = ''
i = 0
for j in range(len(text) + 1):
symbol = s.get(text[i:j])
if symbol is not None:
string += symbol
i = j
print(string)
Out: ++----++--++--+-++++++-+-+-----++-+---+-+---+-++--
