2013-11-13 1 views
0

Я не делал слишком горячего теста, который я недавно взял в классе. Однако, поскольку все остальные тоже бомбили его, наш профессор готов дать нам некоторые «макияжные» баллы, доказав ей, что мы знаем Схему (не так уж хорошо в ней ...). Тем не менее, она задавала разные вопросы из того, что было в тесте. Поэтому я работаю над вопросами, которые были на экзамене, чтобы улучшить работу с Scheme, и я не могу заставить работать на следующий.Я не могу получить функцию Scheme для рекурсивного вызова f во вложенном списке для правильного результата

Запишите функцию схемы, которая принимает два параметра: f, функцию, которая принимает один параметр, и x, произвольное значение. Функция сокращения рекурсивно вызывает f, используя каждый вложенный список, содержащийся в x, и затем заменяет исходный вложенный список результатом вызова f.

Например, применение (уменьшение (лямбда (х) (минусы 'список х))' (3 7 9 ZS (3 (78 2 3)))) должен возвращать:

«(список 3 7 9 zs (список 3 (список 78 2 3)))

Кроме того, обращение (сокращение (лямбда (x) (cdr x)) '(3 7 9 zs (3 (78 2 3)))) должно быть возвращено :

'(7 9 zs ((2 3))), где первый элемент удаляется из каждого вложенного списка.

Это код, который я придумал:

(define reduce 
    (lambda (f x) 
    (if (null? x)'() 
    (let ((var (car x))) 
    (cond 
     ((cons? var) (cons (f var) (reduce f (cdr x)))) 
     ((symbol? var) (cons var (reduce f (cdr x)))) 
     ((number? var) (cons var (reduce f (cdr x))))))))) 

Если я ввожу пример входы, это мои результаты:

(уменьшающие (лямбда (х) (Cons «список х)) '(3 7 9 ZS (3 (78 2 3))))

(список 3 7 9' г 'ы (список' список 3 (список 78 2 3)))

есть дополнительный список, который знает, где

;

(уменьшить (лямбда (X) (CDR X)) '(3 7 9 ZS (3 (78 2 3))))

(список 3 7 9' г «ы (список (список 78 2 3)))

он удаляет только 3 во 2-й вложенной петле. Он должен удалить 3 в первом, 3 в середине и 78 в 3-м. В нем также не должно быть слова «список»

;

Я предполагаю, что проблема находится в строке ((минусы? Вар), но я не могу показаться, чтобы выяснить, как это исправить.

Мы не пошли слишком далеко в языке Scheme , поэтому мы не научились всего много специальных методов, это в основном всего лишь рекурсии

Любая помощь будет высоко ценится

Спасибо...

ответ

1

Вот моя реализация:

(define (reduce f x) 
    (define (inner x) 
    (if (list? x) 
     (f (map inner x)) 
     x)) 
    (inner x)) 

Примеры:

> (reduce (lambda (x) `(list ,@x)) '(3 7 9 z s (3 (78 2 3)))) 
(list 3 7 9 z s (list 3 (list 78 2 3))) 
> (reduce cdr '(3 7 9 z s (3 (78 2 3)))) 
(7 9 z s ((2 3))) 

Вот версия, которая не использует map непосредственно, но в основном переопределяет map (хотя и с использованием жёстко прописанные трансформатора):

(define (reduce f x) 
    (define (transform lst) 
    (if (null? lst) 
     '() 
     (cons (process (car lst)) (transform (cdr lst))))) 
    (define (process x) 
    (if (list? x) 
     (f (transform x)) 
     x)) 
    (process x)) 
+0

ничего себе, это выглядит намного проще. К сожалению, мы никогда не покрывали «карту», ​​но так ли это без нее? – user2869231

+0

@ user2869231 Хорошо, код будет немного длиннее, но вот версия, которая в основном переделывает «карту» для вас. –

+0

так что вы сделали первую часть минусов отдельной функцией. Делает это легче, чем то, что я пытался сделать. Благодаря! – user2869231