Я только начинаю изучать питон, и у меня есть это упражнение, которое меня озадачивает: Создайте функцию, которая может упаковать или распаковать строку букв. Итак, aaabb будет упакован a3b2 и наоборот.Python - упаковка/распаковка буквами
Для упаковки части функции, я написал следующее
def packer(s):
if s.isalpha(): # Defines if unpacked
stack = []
for i in s:
if s.count(i) > 1:
if (i + str(s.count(i))) not in stack:
stack.append(i + str(s.count(i)))
else:
stack.append(i)
print "".join(stack)
else:
print "Something's not quite right.."
return False
packer("aaaaaaaaaaaabbbccccd")
Это, кажется, работает все собственно. Но в задании указывается, что , если на входе есть (например) буква a после b или c, тогда он должен быть впоследствии распакован в первоначальную форму. Итак, «ааббкка» должна стать a3b2k2a, а не a4b2k2. Я поэтому полагал, что я не могу использовать команду count(), так как , которая подсчитывает все вхождения элемента во всей строке, правильно? Какие у меня были бы варианты?
Переходим к распаковке - Я думал об основах, что мой код нужно сделать -
- между «если s.isalpha():» и еще, я должен добавить, что Элиф проверяет, имеет ли строка в нем цифры. (Я полагал, что это будет достаточно, чтобы определить, упакована ли она или распакована).
Создать цикл и внутри него если приговор, который затем проверяет каждый элемент:
2.1. Если у него есть число за ним> Возврат (или добавление в пустой стек) число раз после цифры
2.2. Если у него нет номера, следующего за ним> Верните только элемент.
Большой вопрос номер 2 - как я могу проверить, является ли это число или просто еще один алфавитный элемент после элемента в списке? Я предполагаю, что это должно быть сделано с помощью slicing, но это только целые числа. Может ли это быть достигнуто с помощью команды индекса?
Кроме того - если это имеет какое-либо значение - до сих пор я в основном охватывал списки, строки, если и для , и мне сказали, что это упражнение выполнимо только с такими (... так что если вы не хотите, t mind, сохраняя это на самом деле базовым)
Вся помощь приветствуется энтузиастом новичка!
РЕШИТЬ:
def packer(s):
if s.isalpha(): # Defines if unpacked
groups= []
last_char = None
for c in s:
if c == last_char:
groups[-1].append(c)
else:
groups.append([c])
last_char = c
return ''.join('%s%s' % (g[0], len(g)>1 and len(g) or '') for g in groups)
else: # Seems to be packed
stack = ""
for i in range(len(s)):
if s[i].isalpha():
if i+1 < len(s) and s[i+1].isdigit():
digit = s[i+1]
char = s[i]
i += 2
while i < len(s) and s[i].isdigit():
digit +=s[i]
i+=1
stack += char * int(digit)
else:
stack+= s[i]
else:
""
return "".join(stack)
print (packer("aaaaaaaaaaaabbbccccd"))
print (packer("a4b19am4nmba22"))
Так что это мой окончательный код. Почти удалось вытащить все с помощью только циклов и утверждений. В конце концов, хотя мне пришлось ввести цикл while, чтобы решить проблему с несколькими цифрами. Я думаю, мне все же удалось сохранить его достаточно простым. Спасибо тонну миллимозам и всем остальным за щебень!
Для упаковки мой алгоритм будет: иметь индекс «start» и «end». Установите 'start' в 0, затем увеличивайте' end' до тех пор, пока символ в индексе 'end' будет таким же, как и индекс' start'. (Или до тех пор, пока вы не дойдете до конца строки.) Когда символ меняется, выведите начальный символ и «конец запуска» (длина «запуска») символов. Установите 'start'' end', повторите, пока 'start' больше длины строки. – millimoose
(Здесь используется очень распространенное соглашение, в котором, если указывать какой-то интервал с использованием индекса, индекс 'start' является * включенным *, а индекс' end' является * exclusive *. Таким образом, оба они указывают «до» символа.) – millimoose
Я бы обработал распаковку, проверив, есть ли в какой-то момент цифра. Если вы это сделаете, просто прекратите то, что вы делаете, и вызовите функцию распаковки для всей строки. Это использует тот факт, что для неоднозначных строк (например, 'abc') не имеет значения, что вы делаете - ни упаковка, ни распаковка не изменят их - это означает, что безопасно считать, что строка распакована, пока вы не узнаете иначе. – millimoose