двойной по схеме - PullRequest
       40

двойной по схеме

1 голос
/ 25 февраля 2010

Как написать программу в схеме, которая принимает произвольный сексуальное выражение, состоящее из целых чисел и возвращающее сексуальное выражение, идентичное оригинал, но со всеми удвоенными целыми числами?

Ответы [ 6 ]

1 голос
/ 03 марта 2010

Нам нужна процедура, которая принимает S-выражение в качестве входных данных и выводит S-выражение с той же структурой, но где каждое целое число удваивается; как правило, процедура для отображения S-выражений:

(define (double x)
  (if (number? x)
      (* x 2)
      x)))

(define (sexp-map op sexp)
  ...)

(sexp-map double some-sexpression)

Получаемое нами S-выражение (SEXP) будет либо атомом, в этом случае результатом будет (OP SEXP), либо списком S-выражений. В этом случае мы могли бы подумать о том, чтобы отобразить OP через SEXP, но S-выражения вкладываются как можно глубже. На самом деле мы должны отобразить процедуру, которая преобразует каждый элемент в меньшее S-выражение с помощью OP. Хорошо, если вы посмотрите на это, это просто еще один способ описать цель процедуры, которую мы сейчас пытаемся написать. Таким образом, мы можем отобразить SEXP-MAP через SEXP.

Ну, нет, на самом деле мы не можем, потому что SEXP-MAP нужно вызывать с двумя аргументами, а MAP даст ему только один. Чтобы обойти это, мы используем вспомогательную процедуру F с одним аргументом:

(define (sexp-map op sexp)
  (define (f x)
    (if (list? x)
        (map f x)
        (op x)))
  (f sexp))

Ф завершает всю настоящую работу. SEXP-MAP сводится к тому, чтобы быть фасадом, который проще в использовании для программиста.

0 голосов
/ 26 февраля 2010
(map (lambda (x) (* x 2)) '(1 2 3 4 5)) => '(2 4 6 8 10)

Что это делает? (lambda (x) (* x 2)) принимает число и удваивает его, а map применяет эту функцию к каждому элементу списка.

Редактировать: О, но это не будет переходить в деревья.

0 голосов
/ 26 февраля 2010
(define (double E)
  (cond ((null? E) '()) 
        ((list? (car E)) (cons (double (car E)) (double (cdr E))))
        ((number? E) (list E))
        (else (cons (* 2 (car E)) (double (cdr E))))
        ))
0 голосов
/ 25 февраля 2010
An Sexp of numbers is one of  
-- Number  
-- ListOfSexp  

A ListOfSexp is one of  
-- empty  
-- (cons Sexp ListOfSexp)  

Итак, вам понадобится одна функция для обработки обоих этих определений данных. Поскольку определения данных перекрестно ссылаются друг на друга, функции будут делать то же самое. Каждая отдельная функция довольно проста.

0 голосов
/ 25 февраля 2010

Звучит так, будто вы хотите найти каждое целое число в s-выражении, а затем удвоить его, оставив остальное тем же.

Если вы не знаете, s-выражения - это просто списки, которые могут содержать другие списки, и имеет смысл работать с ними по уровням. Например, вот способ вывести все значения на первом уровне s-выражения:

(define (print-level-one sexp)
  (display (car sexp))
  (print-level-one (cdr sexp)))

Это приведет к вызову display на car каждой части s-выражения.

Вы могли бы сделать что-то подобное. Вам понадобятся функции integer? и pair?, чтобы проверить, является ли что-то целым числом, которое должно быть удвоено, или другим списком, который должен обрабатываться так же, как список верхнего уровня.

(Примечание: я умышленно расплывчато из-за комментария о домашнем задании выше. Если вы просто хотите получить ответ, а не пытаетесь выяснить ответ, скажите это, и я изменю это.)

0 голосов
/ 25 февраля 2010
(define double
    (lambda (x)
      (cond ((null? x) (list))
        ((list? (car x)) (cons (double (car x)) (double (cdr x))))
        (else (cons (* 2 (car x)) (double (cdr x)))))))

EDIT Исправлено это. Спасибо Натану Сандерсу за то, что он указал на мой начальный контроль над вложенными списками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...