Предотвращение ошибок Питона в алгоритме RLE - PullRequest
1 голос
/ 04 ноября 2019

РЕДАКТИРОВАТЬ: в этом есть что-то большее, чем просто ошибка "поштучно".

В следующем простом алгоритме я обнаружил ошибку "поштучно", которая должна отображатьколичество букв в строке вдоль строк run-length encoding.

Я могу понять, почему последний символ не добавляется в строку результата, но если я увеличу range до i Iполучить index out of range по понятным причинам.

Я хочу знать, в чем здесь концептуальная проблема с точки зрения разработки алгоритма, а также просто заставить мой код работать.

Нужно ли мне немногоспециальный регистр кода для обработки последнего элемента в исходной строке? Или, может быть, имеет смысл сравнивать текущий символ с символом previous, хотя это создает проблему в начале алгоритма?

Существует ли общий подход к алгоритму такого типа, где текущийэлементы сравниваются с предыдущими / следующими элементами, что позволяет избежать проблем с индексом вне диапазона?

def encode(text):
    # stores output string
    encoding = ""
    i = 0

    while i < len(text) - 1:
        # count occurrences of character at index i
        count = 1
        while text[i] == text[i + 1]:
            count += 1
            i += 1

        # append current character and its count to the result
        encoding += text[i] + str(count) 
        i += 1

    return encoding

text = "Hello World"
print(encode(text))
# Gives H1e1l2o1 1W1o1r1l1

Ответы [ 2 ]

1 голос
/ 04 ноября 2019

Если вы придерживаетесь своей стратегии, вам придется проверить i+1 < len(text). Это дает что-то вроде:

def encode(text): 
    L = len(text) 
    start = 0 
    encoding = '' 
    while start < L: 
        c = text[start] 
        stop = start + 1 
        while stop < L and text[stop] == c: 
            stop += 1 
        encoding += c + str(stop - start) 
        start = stop 
    return encoding

Еще один способ сделать что-то, это запомнить начало каждого запуска:

def encode2(text): 
     start = 0 
     encoding = '' 
     for i,c in enumerate(text): 
         if c != text[start]: 
             encoding += text[start] + str(i-start) 
             start = i
     if text:
         encoding += text[start] + str(len(text)-start) 
     return encoding

Это позволяет вам просто перечислить ввод, который кажется более питоническим.

1 голос
/ 04 ноября 2019

Вы правы, у вас должно быть while i < len(text) для внешнего цикла, чтобы обработать последний символ, если он отличается от предыдущего (d в вашем случае).

Ваш алгоритм тогдав общем, хорошо, но он вылетает при поиске вхождений последнего символа. На этом этапе text[i+1] становится недопустимым.

Чтобы решить эту проблему, просто добавьте проверку безопасности во внутренний цикл: while i+1 < len(text)

def encode(text):
    # stores output string
    encoding = ""
    i = 0

    while i < len(text):
        # count occurrences of character at index i
        count = 1
        # FIX: check that we did not reach the end of the string 
        # while looking for occurences
        while i+1 < len(text) and text[i] == text[i + 1]:
            count += 1
            i += 1

        # append current character and its count to the result
        encoding += text[i] + str(count) 
        i += 1

    return encoding

text = "Hello World"
print(encode(text))
# Gives H1e1l2o1 1W1o1r1l1d1
...