试图压缩字符串

时间:2016-01-29 22:09:45

标签: string loops python-3.x

我正在尝试创建一个字符串,有些像'aaaabbbcc'压缩成'a4b3c2'。 我已经计算了'a'和压缩权,就像这个'a4',但我该如何继续?这是我的计划:

     def compress(estring):
        cstring= ''
        ct2=0
        npos = estring[ct2]

        ct=0
        for char in estring:
            if char == npos:
                ct+=1
                ct2+=1

        cstring += npos + str(ct)
        return cstring

3 个答案:

答案 0 :(得分:0)

这是我的解决方案。它使用迭代的速度优势(而不是索引)并以线性时间运行。

def compress(string):
    prevchar = string[:1]
    cnt = 1
    result = []
    for char in string[1:]:
        if char == prevchar:
            cnt += 1
        else:
            result.append(prevchar+str(cnt))
            cnt = 1
        prevchar = char
    return ''.join(result) + prevchar + str(cnt)

我已经用timeit测试了它,它似乎比上面的解决方案运行得快一点。缺点是我的解决方案不那么pythonic:

import timeit
avg = lambda x: sum(x) / len(x)

avg(timeit.repeat(
      stmt = lambda: compress('aaaabbbcc'),
      repeat = 100,
      number = 1000))

在我的机器上给我24.7毫秒,而其他人在28-46范围内

它也非常通用,不仅可以用于字符,还可以用于字符串:

compress(['ba','ba','ba','boon','boon'])
#Gives 'ba3boon2'

答案 1 :(得分:0)

您可以使用正则表达式将字符串拆分为重复的部分,然后创建一个计算这些部分的新字符串,例如:

import re


REPETITIONS_REGEXP = re.compile(r'(.)(\1*)')  # match any char and its repetitions

def compact(data):    
    # Get a list with chars and repetions, like [('a', 'aaa'), ('b', 'bb'), ...]
    result = REPETITIONS_REGEXP.findall(data)
    # Create a new string with "char" + (its repetitions + 1)
    return ''.join(['{}{}'.format(x, len(y) + 1) for (x, y) in result])

print compact('aaaabbccc')  # will print 'a4b2c3'

答案 2 :(得分:-1)

itertools.groupby将为您完成所有工作:

s = 'aaaabbbcc'
from itertools import groupby

print("".join([k+str(sum(1 for _ in v)) for k, v in groupby(s)]))
a4b3c2

如果你必须使用一个函数,跟踪最后一个char,当你遇到一个与前一个不相同的char时产生char和当前计数,然后重置计数并继续:

def compress(s):
    it = iter(s)
    prev, i = next(it), 0
    for ch in s:
        if ch != prev:
            yield prev + str(i)
            i = 0
        prev = ch
        i += 1
    yield prev + str(i)

print("".join(compress(s)))

输出相同:

a4b3c2