Вопрос

У меня есть функция, которая получает x(значение) и xs(список) и удаляет из списка все значения, превышающие x.Ну, это не работает, можете сказать мне, почему?

(defun biggerElems(x xs) 
  (let ((xst))
    (dolist (elem xs)
      (if (> x elem)
          (setf xst (remove elem xs))))
    xst))
Это было полезно?

Решение

Я думаю, что эта строка неверна:

(setf xst (remove elem xs))))

Первый аргумент для setf это место, за которым следует значение.Похоже, у вас все наоборот (и xst либо nil или неинициализированный).

Возможно, вам будет проще сделать это:

(defun biggerElems (x xs)
  (remove-if (lambda (item) (> item x)) xs))

Другие советы

Самый краткий AFAIK:

(defun bigger-elements (x xs) (remove x xs :test #'<))

возвращая свежий список, он удаляет все элементы y из xs, для которых

(< y x)

или используя знаменитый LOOP:

(defun bigger-elements-2 (x xs) 
  (loop for e in xs
        unless (< e x)
        collect e))

Это работало так:

(defun filterBig (x xs)
  (remove-if (lambda (item) (> item x)) xs))

Для чего нужен был знак «#»?Он не скомпилировался с ним.

Если вы хотите сделать это с помощью Lisp, вы можете использовать рекурсию для возврата нового списка:

(defun biggerElems (x xs)
  (cond ((null xs) NIL)
        ((< x (car xs))
         (biggerElems x (cdr xs)))
       (t
        (cons (car xs) (biggerElems x (cdr xs))))))

@Луис Оливейра

Это решение контрастирует с решением, опубликованным в вопросе.Если бы нам нужно было сделать что-то более сложное, важно было бы опираться на рекурсивный подход к манипулированию списками.

@Бен:Неправильный не вызов setf — проблема в том, что он не обновляет xs.

то есть:xst устанавливается на xs с удаленным элементом, но xs не обновляется.Если второй элемент должен быть удален, xst вернет в него первый элемент.

вам нужно будет связать xst с xs и заменить xs в вызове удаления на xst.Затем это приведет к удалению всех элементов, которые больше x.то есть:

(defun biggerElems(x xs)
  (let ((xst xs))
    (dolist (elem xs)
      (when (> x elem)
        (setf xst (remove elem xst))))
    xst))

Возможно, было бы немного быстрее установить для xst значение (список копирования xs), а затем использовать удаление вместо удаления (удаление разрушительно...в зависимости от вашей реализации это может быть быстрее, чем удаление.Поскольку вы вызываете это несколько раз, вы можете повысить производительность, скопировав список один раз и удалив его из него).

Альтернативно:

(defun bigger-elems (x xs) ; I prefer hyphen separated to camelCase... to each his own
  (loop for elem in xs when (<= x elem) collect elem))

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

Для чего нужен был знак «#»?Это не компилировало с этим.

Опечатка.Обычно вы ссылаетесь на функции с #' (нравиться (remove-if #'oddp list)), но когда я редактировал, я забыл удалить «#».

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top