2017-01-05 4 views
1

У меня проблема с многоуровневой рекурсией. У меня есть два номера n1 и n2. Когда counter находится между n1 и n2, я хочу, чтобы в результате сохранялись номера нулей, сохраняя внутреннюю структуру списка.Многоуровневая рекурсия в lisp

(defun izdvoj (lista n1 n2 counter) 
    (cond ((null lista) counter) 
     ((and (atom (car lista)) 
       (< counter n1) 
       (izdvoj (cdr lista) n1 n2 (+ counter 1)))) 
     ((and (atom (car lista)) 
       (> counter n2) 
       (izdvoj (cdr lista) n1 n2 (+ counter 1)))) 
     ((atom (car lista)) 
     (cons (car lista) (izdvoj (cdr lista) n1 n2 (+ counter 1)))) 
     (t 
     (cons (izdvoj (car lista) n1 n2 counter) (izdvoj (cdr lista) n1 n2 counter))))) 

(izdvoj '(1 2 (3 (4) 5 (6 (7)))(8 (9 (10 ((11))) 12)) (13 ((14) (15)))) 7 13 0) 

Результат должен быть ((((7))) (8 (9 (10 ((11))) 12)) (13))

И я получаю (((4) ((7))) (((((11))) 12)) (((14) (15))))

Любые предложения, пожалуйста?

+0

Что бы результат '(izdvoj«(аб (кд (е (е))) (GH)) 3 5 0) '? Что такое '' brojac''? Поскольку 'counter' используется, когда список пуст, все списки в результате должны быть пунктирными, как' (d (e (f. 6). 5). 4) '? – Sylwester

+0

Не могли бы вы использовать английские имена переменных и функций? Неясно, что вы делаете. – sds

+0

brojac то же, что и счетчик, и результат (издвойа) (a b (c d (e (f))) (g h)) 3 5 0), должен быть ((c d (e()))()) –

ответ

0

Самый простой способ сделать это - вернуть индекс так же хорошо, как и результат в помощнике. Таким образом, вы знаете, как продолжить, когда вы сделали car и готовы сделать cdr:

(defun get-range (list from-index to-index) 
    (labels ((aux (list cur acc) 
      (cond ((null list) 
        (values (nreverse acc) cur)) 
        ((not (atom (car list))) 
        (multiple-value-bind (res cur) 
             (aux (car list) cur '()) 
         (aux (cdr list) cur (cons res acc)))) 
        ((<= from-index cur to-index) 
        (aux (cdr list) (1+ cur) (cons (car list) acc))) 
        (t (aux (cdr list) (1+ cur) acc))))) 
    (nth-value 0 (aux list 1 '())))) 

(get-range '(a b (c d (e (f))) (g h)) 3 5) 
; ==> ((c d (e()))()) 
Смежные вопросы