3

'1254,,,,,,,,,,,,,,,982' など、同じ文字のブロックを含む文字列があります。私が目指しているのは、それを「1254(,16)982」の行に沿ったものに置き換えて、元の文字列を再構築できるようにすることです。誰かが私を正しい方向に向けることができれば、それは大歓迎です

4

3 に答える 3

7

ランレングス エンコーディングを探しています。これは、これに大まかに基づいた Python 実装です。

import itertools

def runlength_enc(s):
    '''Return a run-length encoded version of the string'''
    enc = ((x, sum(1 for _ in gp)) for x, gp in itertools.groupby(s))
    removed_1s = [((c, n) if n > 1 else c) for c, n in enc]
    joined = [["".join(g)] if n == 1 else list(g)
                    for n, g in itertools.groupby(removed_1s, key=len)]
    return list(itertools.chain(*joined))

def runlength_decode(enc):
    return "".join((c[0] * c[1] if len(c) == 2 else c) for c in enc)

あなたの例:

print runlength_enc("1254,,,,,,,,,,,,,,,,982")
# ['1254', (',', 16), '982']
print runlength_decode(runlength_enc("1254,,,,,,,,,,,,,,,,982"))
# 1254,,,,,,,,,,,,,,,,982

(これは、文字列に非常に長いランがある場合にのみ効率的であることに注意してください)。

于 2012-10-29T13:30:52.013 に答える
3

正確な圧縮形式を気にしない場合は、 と を参照しzlib.compressてくださいzlib.decompresszlib単一の文字列を圧縮できる標準の Python ライブラリであり、おそらく自己実装の圧縮アルゴリズムよりも優れた圧縮が得られます。

于 2012-10-29T13:51:41.343 に答える
1

正規表現を使用:

s = '1254,,,,,,,,,,,,,,,,982'

import re
c = re.sub(r'(.)\1+', lambda m: '(%s%d)' % (m.group(1), len(m.group(0))), s)
print c # 1254(,16)982

itertools の使用

import itertools
c = ''
for chr, g in itertools.groupby(s):
    k = len(list(g))
    c += chr if k == 1 else '(%s%d)' % (chr, k)
print c # 1254(,16)982
于 2012-10-29T15:53:54.703 に答える