문제
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 #'<))
새로운 목록을 반환하면 xs에서 y 요소를 모두 제거합니다.
(< 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를 (copy-list 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)
) 그런데 편집할 때 '#'을 삭제하는 것을 잊어버렸습니다.