Переполнение стека вызовов функций - PullRequest
2 голосов
/ 10 октября 2019

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

(summit2 '(0 nil 1 2))

Error: Received signal number -3 (function call stack overflow (delayed response))
[condition type: ASYNCHRONOUS-OPERATING-SYSTEM-SIGNAL]

Я попытался изменить ноль на ноль. Я также пытался использовать эквалайзер в отличие от эквалайзера.

(defun summit2 (lst)
    (if (eql (car lst) null)
        (summit2 (cdr lst))
      (+ (car lst) (summit2 (cdr lst)))))

ожидаемый результат должен быть 3, сумма элементов в списке, которые не равны nil

Ответы [ 2 ]

2 голосов
/ 11 октября 2019

Некоторые замечания

  • Вы можете записать свой список list, нет необходимости сокращать его до lst.
  • Все ветви в вашем коде приводят к рекурсивномупозвоните по номеру summit, нет случая, когда вы прекратите вычислять результат. Это бесконечное вычисление занимает место в стеке, поэтому в конечном итоге оно останавливается с переполнением стека.
  • Пожалуйста, сделайте отступ в вашем коде обычным способом (прочитайте, например, это руководство по стилю )

Обратите внимание, что случай, когда элемент равен nil, не сильно отличается от случая, когда список ввода пуст. С помощью следующего кода оба обрабатываются одинаково:

(defun sum (val)
  (if (consp val)
      (+ (sum (car val))
         (sum (cdr val)))
      (or val 0)))

Это также означает, что код может делать больше, чем ожидалось, т.е. вы можете суммировать числа в дереве:

(sum '(0 1 2 nil 4 5 7 (1 2)))
=> 22

И это также работает, когда вводом является просто число:

(sum 5)
=> 5
2 голосов
/ 11 октября 2019

Прежде всего, проверка для nil должна выполняться с использованием функции NULL, поэтому в вашем случае (null (car lst)). Во-вторых, вашей рекурсии не хватает базового случая (ошибка, которую вы получаете, указывает на переполнение стека из-за бесконечной рекурсии). Теперь вы только различаете, является ли следующий элемент nil или не nil. Вам нужен третий случай для обработки пустого списка. Это предполагает использование COND. Вы можете, например, сделать что-то вроде:

(defun summit2 (lst)
  (cond 
    ((null lst)
     0)
    ((null (car lst))
     (summit2 (cdr lst)))
    (t
     (+ (car lst) (summit2 (cdr lst))))))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...