【问题标题】:Shortening a string缩短字符串
【发布时间】:2017-11-11 04:55:10
【问题描述】:

我有一个字符串:

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”模式来做到这一点,但这需要对每个可能的字符串都是可行的。有没有人遇到过类似的情况?

【问题讨论】:

  • 这是模棱两可的。 aaabbbaaabbb 的预期输出是什么?是(a)3(b)3(a)3(b)3 还是(aaabbb)2
  • @Nenad 为什么?算法如何知道?
  • @SvenMarnach,最长匹配?我认为这样可以节省最多的空间。
  • 这对codegolf.stackexchange.com来说可能是个好问题

标签: python algorithm python-3.x


【解决方案1】:

您可以使用regex 轻松做到这一点:

>>> repl= lambda match:'({}){}'.format(match.group(1), len(match.group())//len(match.group(1)))
>>> re.sub(r'(.+?)\1+', repl, 'babababbaaaaababbbab')
'(ba)3(b)2(a)5ba(b)3ab'

这里不多解释。模式(.+?)\1+ 匹配重复的字符序列,lambda 函数将它们重写为(sequence)number 的形式。

【讨论】:

  • 太棒了!我想我可能会花时间来掌握正则表达式。非常好的答案。
  • 对于aabaabaab,这给出了一个相当不直观的(a)2(baa)2b而不是(aab)3。虽然这并不是说它是错误的 - 问题有点未明确。
  • @Dukeling 这符合 OP 的声明,即 aaabbbaaabbb 将变为 (a)3(b)3(a)3(b)3 - 它重复最短的可能序列。如果不希望这样做,您可以尝试将 (.+?)\1+ 更改为 (.+)\1+,尽管这也有一些奇怪的怪癖 - 例如,它会将 abababab 变为 (abab)2
【解决方案2】:

这是我想出来的,代码乱七八糟,但我只是想快点玩,所以我让它变成这样

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)

它使 巴巴巴巴巴巴巴巴巴 => (ba)3(b)2(a)5ba(b)3ab

附:当然,划船的答案更好,甚至令人印象深刻

【讨论】:

    【解决方案3】:

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

    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)')
    

    【讨论】:

    • 这似乎没有为问题中的示例提供正确的输出,更不用说更普遍的问题了。
    猜你喜欢
    • 2011-04-28
    • 2019-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 1970-01-01
    • 2011-01-08
    • 1970-01-01
    相关资源
    最近更新 更多