2012-03-16 3 views
1

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

Я написал программу, которая берет список символов и собирает их для создания слов. Слово заканчивается, когда в списке есть «». Так что, похоже, что:

inp = ['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k'] 
outp = ['reel', 'yellow', 'gel', 'peek'] 

код выглядит следующим образом:

def mer(inp, outp=[]): 
    tail = 0 
    for item in inp: 
     if item == (" "): 
      inp[:tail] = ["".join(inp[:tail])] 
      outp.append(inp.pop(0)) 
      inp.remove(item) 
     if ((" ") in inp) == False: 
      inp[:] = ["".join(inp[:])] 
      outp.append(inp.pop(0))   
     tail +=1 

И теперь, чтобы получить выход (в случае с входом, как сверху) мне нужно позвонить Мер два раза , Есть ли способ заставить его работать до тех пор, пока список ввода не будет пустым или, возможно, не будет использовать рекурсию?

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

+0

Да, это может быть сделано с помощью рекурсии. В общем, все, что вы можете писать с использованием циклов, может быть записано рекурсивно и наоборот, хотя вам, возможно, придется использовать дополнительные структуры данных, такие как стеки. Постскриптум Это домашнее задание? Если это так, он должен быть помечен как таковой. – skytreader

+0

Хорошо, спасибо. Нет, это не домашнее задание, просто моя собственная идея что-то делать. – Iscario

+0

Спасибо за все ответы, в то время как лучшая команда для выполнения этой работы - использовать join и split (спасибо kev, Alasdair), я хотел знать, как что-то вроде моего вопроса будет выглядеть с рекурсией. Cheers – Iscario

ответ

2

И теперь, чтобы получить выход (в случае с входом, как на вершине), мне нужно позвонить Мер два раза.

Проблема с вашим алгоритмом заключается в том, что вы изменяете список во время его перебора. Это озорная и небезопасная вещь.

После "reel" помещается в outp, inp является ['y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']. Но следующий символ, который будет рассмотрен в цикле, - это, по крайней мере, реализация CPython, а не 'y''yellow', но 'w'. Это происходит потому, что итерация внутренне хранит индекс (который, случается, синхронизируется с переменной tail, которую вы обновляете вручную) и использует это для захвата элементов. listiterator, созданный за кулисами для реализации цикла for, совершенно не знает об изменениях в list, которые он выполняет итерации, и, следовательно, не может настроить, чтобы сохранить «ту же позицию» (и кто знает, что вы на самом деле подразумеваете под этим, в любом случае ?).

Вы можете увидеть это сами, если добавить в код несколько команд «trace» print, чтобы показать состояние переменных в разных точках.

В любом случае, так как итератор находится на 'w', он найдет место рядом и извлечет 'yellow' просто отлично; но затем он переместится на 'k'"peek", пропустив пробел после 'gel', и он не будет запускать какой-либо код в вашем втором случае if, потому что пробел между 'gel' и 'peek' все еще находится в буфере (вы на самом деле не достаточно ясно о реальном состоянии конца).

Если вы действительно хотите сделать все, что вам нужно, а не просто написать ''.join(inp).split(' '), вы можете исправить эту проблему, отслеживая индекс начала слова и конца слова, вырезая подсписки, присоединяя их и помещая полученные слова в выходной сигнал, и оставляя вход только. Хотя мы находимся в этом:

  • функции должны использовать возвращаемое значение для возврата данных; прохождение в параметре outp глупо - давайте просто вернем список слов.

  • Мы можем использовать встроенную функцию enumerate, чтобы получить индексы, которые соответствуют элементам списка при повторении.

  • Я понятия не имею, что означает «mer».

  • Вы используете слишком много круглых скобок и сравниваете с булевыми литералами (True и False) - это плохой стиль.

Таким образом, исправленный код с использованием оригинального алгоритма:

def words_from(chars): 
    begin = 0 # index of beginning of current word 
    result = [] # where we store the output 
    for i, char in enumerate(chars): 
     if char == ' ': 
      result.append(''.join(chars[begin:i])) 
      begin = i + 1 
    # At the end, make one more word from the chars after the last space. 
    result.append(''.join(chars[begin:])) 
    return result 
+0

Вау, это действительно полезно, спасибо. Я просто изучаю так, поэтому в этом коде есть так много «странных» вещей. И вы правы, теперь, когда я думаю об этом (и имею Ваше решение здесь), мой был довольно плохо продуман, и некоторые вещи не работали, как предполагалось. Мне еще предстоит пройти долгий путь ... – Iscario

+0

Вы очень желанны. Теперь, пожалуйста, просто напишите '. '.join (inp) .split (' ')' и расслабьтесь. :) –

4

Вы можете использовать join и split:

>>> ''.join(inp).split() 
['reel', 'yellow', 'gel', 'peek'] 

# recursion 
from itertools import takewhile 

def fun(x): 
    if not x: 
     return 
    y = list(takewhile(lambda i:i!=' ', x)) 
    yield ''.join(y) 
    for z in fun(x[len(y)+1:]): 
     yield z 

list(fun(['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k'])) 
3

Я знаю, что вы попросили для метода с использованием рекурсии, но самый вещий способ в этом случае, чтобы присоединиться символы вместе, то расколоть их.

outp = "".join(input).split(" ") 
2

Вы определенно должны использовать join и split для этого, но так как этот вопрос конкретно просит рекурсивного решения, вот ответ, который использует один.

Это подразумевается как упражнение только в рекурсии, этот код не должен использоваться.

def join_split(inp, outp=None): 
    if not inp: 
     return outp 
    if inp[0] == ' ': 
     return join_split(inp[1:], (outp or ['']) + ['']) 
    if outp is None: 
     return join_split(inp[1:], [inp[0]]) 
    outp[-1] += inp[0] 
    return join_split(inp[1:], outp) 

>>> join_split(['r','e', 'e', 'l', ' ', 'y', 'e', 'l', 'l', 'o', 'w', ' ', 'g', 'e', 'l',' ', 'p','e','e','k']) 
['reel', 'yellow', 'gel', 'peek'] 
+0

+1 избили меня. Моя версия очень тождественна, хотя и менее питонична. – progo

Смежные вопросы