#python #python-3.x #recursion #stack-overflow
#python #python-3.x #рекурсия #переполнение стека
Вопрос:
Я пытаюсь решить проблему с домашним заданием:
Первые исследователи гор Напьелер в свободное время развлекали себя выкрикиванием различных фраз, чтобы послушать, как звучит эхо. В своих играх они заметили, что первое эхо всегда было частью исходной фразы, а второе было той же частью первого эха, и так далее, пока все не смолкло. Например, в области Napieuler доля составляла приблизительно 0,368.
При выкрикивании фразы длиной 100 секунд первое эхо было длиной 100 * 0,368 секунды. Второй был 100 * 0.368 * 0.368 и так далее, пока это не стало незаметным. Напишите программу, которая текстовым образом приближает эхо гор Напьелер. Программа должна получать с помощью консоли характерную долю эхо-сигнала, которую она хочет аппроксимировать (в виде одного десятичного числа). Затем программе, должно быть, потребуется вызвать рекурсивную функцию, для чего вы должны получить фразу. Наконец, вы должны распечатать все отголоски фразы, включая оригинальную фразу, выкрикнутую человеком. Вы также должны показать общее количество повторений, включая оригинальную фразу. Поскольку вы не можете легко вычислить продолжительность написанной фразы, вы можете предположить, что каждая буква занимает постоянное время, включая пробелы и знаки препинания. Округление умножений в меньшую сторону с получением нецелочисленного результата. Если вы выполните программу правильно, не вызывая рекурсивную функцию, у вас будет 0 в проблеме.
Ваша функция должна быть
Примеры:
Enter the fraction: 0.369
Enter the sentence: I love mac and cheese
I love mac and cheese
cheese
se
Общее количество эхо-сигналов: 3
Enter the fraction: 0.369
Enter the sentence: Today it is not a beautiful spring day. I wish ot was.
Today it is not a beautiful spring day. I wish ot was.
day. I wish it was.
it was.
s.
Total of echoes: 4
Я начал писать код, но продолжаю получать ошибку переполнения стека. Будем признательны за любую помощь.
Код, который продолжает выдавать ошибку переполнения стека:
def echo(a,b):
if len(b)>=2:
return [b] echo(a,b[(-(int(len(b)*a))):])
else:
return []
print(echo(0.369,"I love mac and cheese."))
Ответ №1:
Когда len(b) == 2
тогда len(b) * a == 0.738
, и int(len(b)*a)
есть 0
. -0
это то же самое, что 0
, поэтому вы выполняете рекурсивный вызов с помощью b[0:]
, который такой же, как b
, поэтому вы выполняете рекурсию бесконечно.
Вам нужно прекратить рекурсию, когда int(a * len(b)) == 0
.
def echo(a,b):
newlen = int(len(b)*a)
if newlen > 0:
return [b] echo(a,b[-newlen:])
else:
return [b]
print(echo(0.369,"I love mac and cheese"))
Ответ №2:
Вы можете отладить это самостоятельно, используя несколько простых строк кода. Если вы искусственно ограничите свой код переполнением стека, добавив счетчик, чтобы ограничить его 10 рекурсиями, и добавьте инструкцию print, чтобы видеть состояние вашей программы при каждом рекурсивном вызове, вы можете легко узнать, что делает ваш код, и сравнить его с тем, что вы ожидаете, что он будет делать:
def echo(a,b, counter=0):
if counter < 10 and len(b)>=2:
print('counter is: ', counter, ', I am using index: ', (-(int(len(b)*a))), ' which gives: ', b[(-(int(len(b)*a))):])
return [b] echo(a,b[(-(int(len(b)*a))):], counter 1)
else:
return []
Вызов print(echo(0.369,"I love mac and cheese."))
этого дает нам:
counter is: 0 , I am using index: -8 which gives: cheese.
counter is: 1 , I am using index: -2 which gives: e.
counter is: 2 , I am using index: 0 which gives: e.
counter is: 3 , I am using index: 0 which gives: e.
counter is: 4 , I am using index: 0 which gives: e.
counter is: 5 , I am using index: 0 which gives: e.
counter is: 6 , I am using index: 0 which gives: e.
counter is: 7 , I am using index: 0 which gives: e.
counter is: 8 , I am using index: 0 which gives: e.
counter is: 9 , I am using index: 0 which gives: e.
['I love mac and cheese.', ' cheese.', 'e.', 'e.', 'e.', 'e.', 'e.', 'e.', 'e.', 'e.']
Это означает, что, как сказал Джоран, в конечном итоге вы вычисляете эту часть бесконечно:
'e.'[0:]
которая всегда вычисляется как 'e.'
.
С этими знаниями, я уверен, вы сможете выяснить, что делать, чтобы исправить свой код.
Ответ №3:
на вашей последней итерации у вас есть e.
которая является len 2
вы делаете echo(a,b[-0:])
которая фактически вычисляется как echo(a,b[0:])
которая вызывает ее снова с e.
вам нужно изменить 2 символа (одно удаление и одну вставку), которые исправят ваш код