首页 > 解决方案 > 如何用最短到最长匹配从头到尾替换文本

问题描述

如何用最短到最长匹配从头到尾替换文本

我有数据:

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)

感谢大家的回复,他们导致了这个缩短的版本

标签: pythonstringsubstring

解决方案


这是一个常见的吃功能。你从左边吃,直到你找到与你的字典匹配的东西。

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)

输出:++----++---++--+-++++++-+-+-----++-+---+-+---+-++ --


推荐阅读