Python 编码器和解码器

1 投票
4 回答
2528 浏览
提问于 2025-04-17 13:45

我想用文本编码来制作一个编码器和解码器。

比如说,输入一个字符串 "AAABBBBCDDDDDDDDDDEEDDDD",输出应该是 "A3B4C1D10E2D4",也就是说每个字母后面跟着它在字符串中出现的次数。解码器则是把这个过程反过来。

我希望能得到一些关于如何在Python中开始的帮助。

4 个回答

1

这个问题可以用不同的方法来解决,使用循环的方法其实挺简单的,留给你自己去练习。

为了让你感受一下Python的强大,我这里提供一个使用groupby的方法。

>>> ''.join("{}{}".format(k, sum(1 for e in v))
        for k,v in groupby("AAABBBBCDDDDDDDDDDEEDDDD"))
'A3B4C1D10E2D4'

这个方法的主要特点:

  1. itertools.groupby可以把相似的连续数据分组,形成一个键值对,其中键是重复的元素,值是这些元素的重复组。
  2. 因为这个组是一个生成器,所以len函数可能不适用,但可以用sum来计算任何非序列可迭代对象的长度。
  3. str.join可以把一个可迭代对象连接成一个字符串,并可以指定分隔符,在这个例子中,分隔符是一个空字符串。
1

看看这个问题,虽然不完全是你想要的,但它可以帮助你尝试实现你的目标。

确定密码文本中字母的频率

0

对于编码者来说,一个简单的解决办法就是逐个遍历字符串,数一下每个字符出现的次数,这个方法虽然不复杂,但时间复杂度是O(n),也就是处理速度跟字符串长度成正比。

def encode(s):
    last  = s[0]
    count = 0
    for c in s:
        if last != c:
            yield '%s%i' % (last, count)
            last = c
            count = 0
        count += 1
    yield '%s%i' % (last, count)

而对于解码者,你可以使用正则表达式,这样可以很方便地将字符串分割开来,不需要自己写解析器。

import re

def decode(s):
    for c, n in re.findall(r'(\w)(\d+)', s):
        yield c * int(n)

根据你的测试输入

s = 'AAABBBBCDDDDDDDDDDEEDDDD'

encoded = ''.join(encode(s))
print encoded

decoded = ''.join(decode(encoded))
print decoded

结果是

A3B4C1D10E2D4
AAABBBBCDDDDDDDDDDEEDDDD

还有一点要说明的是,这里其实没有必要使用yield,你当然可以先在编码或解码的函数里构建好字符串,然后再返回。

撰写回答