Python 缩短绳子

Python 缩短绳子,python,algorithm,python-3.x,Python,Algorithm,Python 3.x,我有一个字符串: a = babababbaaaaababbbab 它需要缩短,所以看起来像这样: (ba)3(b)2(a)5ba(b)3ab 所以基本上,它需要记录所有重复的字符,并记录它们重复的次数,而不是打印它们。 我做到了一半: from itertools import groupby a = 'babababbaaaaababbbab' grouped = ["".join(grp) for patt,grp in groupby(a)] solved = [str(len(i)

我有一个字符串:

a = babababbaaaaababbbab
它需要缩短,所以看起来像这样:

(ba)3(b)2(a)5ba(b)3ab
所以基本上,它需要记录所有重复的字符,并记录它们重复的次数,而不是打印它们。 我做到了一半:

from itertools import groupby
a = 'babababbaaaaababbbab'
grouped = ["".join(grp) for patt,grp in groupby(a)]
solved = [str(len(i)) + i[0] for i in grouped if len(i) >= 2]

但这只适用于重复的字符,而不是模式。我知道我可以通过在字符串中找到'ab'模式来实现这一点,但这需要对每个可能的字符串都可行。有人遇到过类似的情况吗?

您可以通过以下方式轻松做到这一点:


这里没什么好解释的。模式。+?\1+匹配重复的字符序列,lambda函数将其重写为sequencenumber格式。

您可以轻松地使用以下方法执行此操作:


这里没什么好解释的。模式。+?\1+匹配重复的字符序列,lambda函数将其重写为sequencenumber格式。

我不确定您到底在寻找什么,但希望这能有所帮助

A=a.count('a')
B=a.count('b')
AB=a.count('ab')
BAB=a.count('bab')
BA=a.count('ba')
print(A,'(a)',B,'(b)',AB,'(ab)',BAB,'(bab)',BA,'(ba)')

我不确定你到底在找什么,但希望这能有所帮助

A=a.count('a')
B=a.count('b')
AB=a.count('ab')
BAB=a.count('bab')
BA=a.count('ba')
print(A,'(a)',B,'(b)',AB,'(ab)',BAB,'(bab)',BA,'(ba)')

这就是我想出来的,代码很混乱,但我只是想快速地玩一玩,所以我就让它变成这样

a = 'babababbaaaaababbbab'

def compress(text):
    for i in range(1, len(text) // 2):
        for j, c in enumerate(text[:-i if i > 0 else len(text)]):
            pattern = text[j:i+j]
            new_text = pattern_repeats_processor(pattern, text, j)
            if new_text != text:
                return compress(new_text)
    return text

def pattern_repeats_processor(pattern, text, i):
    chunk = pattern
    count = 1 
    while chunk == pattern and i + (count + 1) * len(pattern) < len(text):
        chunk = text[i + count * len(pattern): i + (count + 1) * len(pattern)] 
        if chunk == pattern:
            count = count + 1
        else:
            break
    if count > 1:
        return text[:i] + '(' + pattern + ')' + str(count) + text[i + (count + 0) * len(pattern):]
    return text

print(compress(a))
print(a)
它使 巴巴巴巴巴巴巴巴=> ba3b2a5bab3ab


当然,赛艇的答案是英里更好,甚至给人留下深刻印象,这就是我想到的,代码很混乱,但我只是想快速地玩一玩,所以我就让它这样吧

a = 'babababbaaaaababbbab'

def compress(text):
    for i in range(1, len(text) // 2):
        for j, c in enumerate(text[:-i if i > 0 else len(text)]):
            pattern = text[j:i+j]
            new_text = pattern_repeats_processor(pattern, text, j)
            if new_text != text:
                return compress(new_text)
    return text

def pattern_repeats_processor(pattern, text, i):
    chunk = pattern
    count = 1 
    while chunk == pattern and i + (count + 1) * len(pattern) < len(text):
        chunk = text[i + count * len(pattern): i + (count + 1) * len(pattern)] 
        if chunk == pattern:
            count = count + 1
        else:
            break
    if count > 1:
        return text[:i] + '(' + pattern + ')' + str(count) + text[i + (count + 0) * len(pattern):]
    return text

print(compress(a))
print(a)
它使 巴巴巴巴巴巴巴巴=> ba3b2a5bab3ab


当然,赛艇的答案是好几英里,甚至令人印象深刻。这可能是相关的:这是不明确的。AAABBAB的预期输出是多少?是A3B3还是AAABB2?@Nenad为什么?算法怎么知道?@SvenMarnach,最长匹配?这可能是一个好问题,因为这可能是相关的:这是不明确的。AAABBAB的预期输出是多少?是A3B3还是AAABB2?@Nenad为什么?算法怎么知道?@SvenMarnach,最长匹配?我认为这将节省最多的空间。这可能是一个很棒的问题!我想我可能会抽出一段时间来掌握正则表达式。非常好的答案。对于aabaab,这给出了一个相当不直观的a2baa2b而不是aab3。虽然这并不是说它错了-问题有点不明确。@Dukeling这是为了符合OP的说法,即aaabbaabab将成为A3b3-它重复了尽可能短的序列。如果这是不可取的,您可以尝试将.+?\1+更改为.+\1+,尽管这也有一些奇怪的怪癖-例如,它会将abababab变成abab2。太棒了!我想我可能会抽出一段时间来掌握正则表达式。非常好的答案。对于aabaab,这给出了一个相当不直观的a2baa2b而不是aab3。虽然这并不是说它错了-问题有点不明确。@Dukeling这是为了符合OP的说法,即aaabbaabab将成为A3b3-它重复了尽可能短的序列。如果这是不可取的,您可以尝试将.+?\1+更改为.+\1+,尽管这也有一些奇怪的怪癖-例如,它会将abababab转换为abab2。这甚至似乎无法为问题中的示例提供正确的输出,更不用说更一般的问题了。这甚至似乎无法为问题中的示例提供正确的输出,不要管更一般的问题。