Хобрук: Ваш путь к мастерству в программировании

S-выражения и списки Lisp Длина/Размер

Я пытаюсь написать функцию, используя только функции Common Lisp, которые будут подсчитывать количество s-выражений в s-выражении. Например:

((x = y)(z = 1)) ;; returns 2

а также

((x - y)) ;; returns 1

Вложенные выражения возможны так:

((if x then (x = y)(z = w))) ;; returns 3

Я написал функцию, которая находит длину и работает, если нет вложенных выражений. Это:

(define (length exp)
  (cond
    ((null? exp) 0)
    (#t (+ 1 (length (cdr exp))))))

Теперь я изменил это, пытаясь поддерживать вложенные выражения, следующим образом:

(define (length exp)
  (cond
    ((null? exp) 0)
    ((list? (car exp)) (+ 1 (length (cdr exp))))
    (#t (length (cdr exp)))))   

Это работает для выражений без вложений, но всегда на 1 меньше, чем ответ для вложенных выражений. Это связано с тем, что в приведенном выше примере, ((if x then (x = y)(z = w))), сначала будет рассматриваться if, что удовлетворяет третьему условию, возвращая cdr (остальную часть выражения в виде списка) в length. То же самое происходит до тех пор, пока не будет достигнуто (x=y), после чего возвращается +1. Это означает, что выражение (if x then .... ) не было учтено.

Каким образом я мог бы объяснить это? Добавление +2 приведет к пересчету не вложенных выражений.

Мне нужно, чтобы это работало в одной функции, так как вложение может происходить где угодно, поэтому:

((x = y) (if y then (z = w)))

  • Это выглядит странно. Вы говорите: «Я пытаюсь написать функцию, используя только функции Common Lisp». Тем не менее, ваш код находится в Scheme? 28.11.2012
  • @RainerJoswig мой код находится в схеме, но я использую только числовые примитивы, предикаты и функции LISP. 28.11.2012
  • хорошо, но это не имеет ничего общего с Common Lisp. У Common Lisp много функций — больше, чем образовательная схема. 28.11.2012
  • @RainerJoswig Хорошо, я действительно не знаю разницы, я только начал работать со Scheme. 28.11.2012

Ответы:


1

На первый взгляд, ваш код рекурсирует только вправо (со стороны cdr), а не влево (со стороны автомобиля), так что это определенно проблема.

На второй взгляд, это даже немного сложнее, потому что вы не совсем считаете минусы; вам нужно различать случай, когда минусы начинают правильный список и когда это cdr списка. Если вы вернетесь к car и cdr, эта информация будет потеряна. Нам нужно перебрать секс-выражение как правильный список,

(defun count-proper-list (sexp)
  (cond ((atom sexp) 0)
        (t (1+ (reduce #'+ (mapcar #'count-proper-list sexp))))))

Но это также будет учитывать список верхнего уровня, поэтому всегда возвращайте на один больше, чем вам кажется. Так что, возможно,

(defun count-proper-sublist (sexp)
  (1- (count-proper-list sexp)))
28.11.2012
  • Спасибо. Я не уверен, что делают mapcar или reduce, но мне не разрешено использовать их для этого. Я вижу, где моя проблема. Дело в том, что мне не хватает некоторых списков или элементов в моей рекурсии. Говоря концептуально, мне нужно пройтись по секс-экспрессу как по правильному списку. 1- Как это делается? 2- Как бы я все еще обнаруживал вложенные секс-файлы? Извините, я не все понял. 28.11.2012
  • Новые материалы

    Решения DBA Metrix
    DBA Metrix Solutions предоставляет удаленного администратора базы данных (DBA), который несет ответственность за внедрение, обслуживание, настройку, восстановление базы данных, а также другие..

    Начало работы с Блум
    Обзор и Codelab для генерации текста с помощью Bloom Оглавление Что такое Блум? Некоторые предостережения Настройка среды Скачивание предварительно обученного токенизатора и модели..

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

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

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