как считать повторяющиеся символы в строке в Python - PullRequest
1 голос
/ 17 июня 2019

Напишите функцию python, которая выполняет кодирование длины серии для заданной строки и возвращает закодированную строку длины строки.

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

def encode(message):    
    #Remove pass and write your logic here
    count=0
    encoded_message=[]
    for char in range(0,len(message)-1,1):
        count=1
        while(message[char]==message[char+1]):

             count=count+1;
             char=char+1
        encoded_message.append(str(count)+message[char])

    return encoded_message

encoded_message=encode("ABBBBCCCCCCCCAB")
print(' '.join(encoded_message))

ожидаемый результат - 1A4B8C1A1B. что я получил, это 1A 4B 3B 2B 1B 8C 7C 6C 5C 4C 3C 2C 1C 1A

Ответы [ 5 ]

4 голосов
/ 17 июня 2019

Вы можете использовать groupby из itertools модуля:

s = "ABBBBCCCCCCCCAB"
from itertools import groupby
expected = ''.join([str(len(list(v)))+k for k,v in groupby(s)])

Выход :

'1A4B8C1A1B'

groupby(s) возвращает объект itertools.groupby. Понимание списка для этого объекта, например [(k,list(v)) for k,v in groupby(s)], возвращает нас упорядоченным образом:

[('A', ['A']), ('B', ['B', 'B', 'B', 'B']), ('C', ['C', 'C', 'C', 'C', 'C', 'C', 'C', 'C']), ('A', ['A']), ('B', ['B'])]

Мы можем просто подсчитать количество подпунктов во втором элементе кортежа и добавить его формат строки перед первым элементом кортежа и объединить их все.

Обновление : Вы пытаетесь изменить индекс итерации в цикле, выполнив char=char+1, но он не меняет индекс итерации, т. Е. Цикл не проходит в течение следующих 2, 3 или 4 итераций. Добавьте эти две строки печати в свой код, и вы увидите, что переменная char, которую вы пытаетесь увеличить во время цикла, - это не просто индекс итерации:

...
for char in range(0,len(message)-1,1):
        print('\tchar at first line : ', char, 'char id now : ', id(char))
        count=1
        while(message[char]==message[char+1]):
            count=count+1
            char=char+1
            print('char now : ', char, 'char id now : ', id(char))
            ...

Это должно вывести что-то вроде:

    char at first line :  1 char id now :  11197408
char now :  2 char id now :  11197440
char now :  3 char id now :  11197472
char now :  4 char id now :  11197504

Видите, как id каждого времени char изменилось.

0 голосов
/ 17 июня 2019

Если вы хотите исправить свою функцию, вот фиксированный вариант:

def encode(message):
    result = []
    i = count = 0
    while i < len(message) - 1:
        count = 1
        while i + count < len(message) and message[i + count - 1] == message[i + count]:
            count += 1
        i += count
        result.append("{}{}".format(count, message[i - 1]))
    if count == 1:
        result.append("1" + message[-1])
    return result

Что изменилось:

  1. для цикл заменен на в то время как .Зачем?Потому что вам нужно перепрыгнуть через индексы внутри цикла.range(0,len(message)-1,1) возвращает ваш список [0, 1, 2, ...], и не имеет значения, что вы делаете с char переменным циклом incide, это не повлияет на следующую итерацию.Чтобы иметь возможность пропустить некоторые индексы, я использовал цикл , в то время как с предопределенным (i = count = 0) индексом и переменными счетчика.
  2. Изменены условия внутреннего цикла , в то время как .Теперь есть два условия:
    • message[i + count - 1] == message[i + count] - проверить, совпадает ли следующий символ с текущим;
    • i + count < len(message) - запретить доступу интенционального цикла к индексу вне диапазона.
  3. Обновление индекса "main" (i) вне внутреннего цикла.
  4. if count == 1: добавлено условие post после выполнения цикла, чтобы не пропустить последний символ в случае, если он одиночный.
0 голосов
/ 17 июня 2019

Используйте эту логику, она вернет вам словарь с частотой каждой буквы.

s = "ABBBBCCCCCCCCAB"
d = {i:0 for i in s}
for i in s:
    d[i] += 1
print(d)

**output:-**
{'A': 2, 'B': 5, 'C': 8}
0 голосов
/ 17 июня 2019
def func(string):
    string +='@'
    dic = []
    tmp =[]
    tmp += [string[0]]

    for i in range(1,len(string)):

        if string[i]==string[i-1]:
            tmp.append(string[i])
        else:
            dic.append(tmp)
            tmp=[]
            tmp.append(string[i])
    res = ''.join(['{}{}'.format(len(i),i[0]) for i in dic])
    return res

string = 'ABBBBCCCCCCCCAB'         
solution = func(string)

print(solution)

выход

1A4B8C1A1B
0 голосов
/ 17 июня 2019

Вы также можете использовать re модуль для кодирования строки:

s = 'ABBBBCCCCCCCCAB'

import re

l = ''.join(str(len(c2)+1) + c1 for c1, c2 in re.findall(r'([A-Z])(\1*)', s))

print(l)

Печать:

1A4B8C1A1B
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...