How can I compress ASCII art into RLE with run lengh of 2 (or decompress RLE into ascii in the same way)?

前端 未结 1 1946
醉酒成梦
醉酒成梦 2021-01-16 08:11

I want to get a program or a function to compress ASCII art from a text file into RLE with a run length of 2, so it counts the amount of characters and displays it like so:

1条回答
  •  别那么骄傲
    2021-01-16 08:22

    I don't really see how your code is supposed to split the string into groups of 2+1 character, but anyway, using a dict or OrderedDict would not work, as even if ordered, a dict can hold any key at most once, i.e. it could not represent an encoded string like 01a01b01a. Instead, you should create a list of tuples, and you can do so using just string slicing and a range with step=3:

    def runLengthEncoding(s):
        return [(int(s[i:i+2]), s[i+2]) for i in range(0, len(s), 3)]
    
    >>> runLengthEncoding("04662312x52c02z01 03a")
    [(4, '6'), (62, '3'), (12, 'x'), (52, 'c'), (2, 'z'), (1, ' '), (3, 'a')]
    

    It is not really clear from your question whether the function is supposed to encode or decode the strings, but judging from your final sentence, I assume you want to decode them. The other direction can easily be done with itertools.groupby and some str.joining:

    # RLE -> Text
    s = "04662312x52c02z01 03a"
    pairs = [(int(s[i:i+2]), s[i+2]) for i in range(0, len(s), 3)]
    # [(4, '6'), (62, '3'), (12, 'x'), (52, 'c'), (2, 'z'), (1, ' '), (3, 'a')]
    text = ''.join(n * c for n, c in pairs)
    # '666633333333333333333333333333333333333333333333333333333333333333xxxxxxxxxxxxcccccccccccccccccccccccccccccccccccccccccccccccccccczz aaa'
    
    # Text -> RLE
    from itertools import groupby
    pairs = [(len(list(g)), k) for k, g in groupby(text)]
    # [(4, '6'), (62, '3'), (12, 'x'), (52, 'c'), (2, 'z'), (1, ' '), (3, 'a')]
    s = ''.join("%02d%s" % (n, c) for n, c in pairs)
    # '04662312x52c02z01 03a'
    

    0 讨论(0)
提交回复
热议问题