@Ozrae

Как работает алгоритм кодирования длин серий?

def rle(src):
    result = []
    if src:
        current = src[0]
        counter = 1
        for e in src:
            if e == current:
                counter += 1
            else:
                result.append((current, counter))
                current = e
                counter = 1
        result.append((counter, current)) # эта строчка не понятна                                              
    return result                                    


string = 'aaabbbtttggghhhavaaa'

print(rle(string))


В итоге код выводит следующее: [('a', 4), ('b', 3), ('t', 3), ('g', 3), ('h', 3), ('a', 1), ('v', 1), (3, 'a')]
В коде комментом указал не понятный мне момент. Видите, что в выходных данных последний элемент другой? Его обрабатывает та самая строка, а все другие обрабатываются в цикле for. Не могу понять почему так происходит, зачем она вообще нужна? Не могу себе представить программу с ней, мне кажется будто эта строка лишняя и все должно работать без неё. Объясните, пожалуйста.
  • Вопрос задан
  • 626 просмотров
Решения вопроса 3
@Andy_U
Я уж не знаю, откуда вы взяли эту программу, но в указанной строке очевидно надо поменять порядок элементов на:
result.append((current, counter))
Также очевидно, что если вы эту строчку выкинете, последний элемент списка (последняя серия) в ответе исчезнет.

Кстати и с длиной первой серии программа провирается. Сами найдете ошибку?
Ответ написан
Комментировать
longclaps
@longclaps
Непонятную строку можно выкинуть:
def rle(src):
    result = []
    # допишем букву, отличающуюся от последней в строке
    src += 'b' if src.endswith('a') else 'a'
    # теперь, заметь, она не пуста и проверка на пустоту не нужна
    current = src[0]
    counter = 0  # тут ошибочка, ты пытался дважды посчитать первую букву
    for e in src:
        if e == current:
            counter += 1
        else:
            result.append((current, counter))
            current = e
            counter = 1
    return result


string = 'aaabbbtttggghhhavaaa'

print(rle(string))
Ответ написан
Комментировать
adugin
@adugin Куратор тега Python
Вообще можно всё сильно упростить:
from itertools import groupby

def rle(text):
    return [(key, len(tuple(group))) for key, group in groupby(text)]
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы