2016-10-05 4 views
1

나는 LISP에서 루프를 사용하는 방법을 이해하려고 노력했지만 여전히 올바르게 작동하지는 않는다. 다음 코드를 사용해 보았습니다.LISP에서 루프를 사용하는 방법

(loop for i from 0 to (list-length y) 
      (when (eq (values-list (nth i (car y))) 0) 
      (return-from checkZero t))) 

내 값이 0인지 아닌지는 내 목록 검사를 반복해야합니다. 같으면 루프에서 돌아와 루프를 종료해야합니다. 그렇지 않으면 목록 길이에 도달 할 때까지 실행해야합니다. 이 잘못에 대해 생각하고 있습니까? 그렇다면이 루프를 수정하는 방법은 무엇입니까?

는 (내 실제 코드가 작동하거나하지 않을 경우 나는 여전히 잘못 사용 루프에 의해 발생하는 오류를 처리하고 있기 때문에 아직 확실하지 않다 나는 온라인 루프를 사용하는 많은 좋은 자원을 찾을 수 없습니다)

+1

이'(때 (EQ 주위에 괄호를 제거 ...) (return-from ...)') 그래서'when (eq ...) (return-from ...)'을하고'do'를'(return-from ...)'앞에 넣으십시오. – Renzo

+4

[Practical Common Lisp] (http://www.gigamonkeys.com/book/)에는 [LOOP for Black Belts]라는 루프가 있습니다 (http://www.gigamonkeys.com/book/loop-for-black). -belts.html). [Lisp의 땅] (http://landoflisp.com/)에서 [실용적인 치트 시트] (http://blog.idorobots.org/media/lolreview/3.png) – Sylwester

답변

4

을 루프의 주된 문제점은 WHEN -expression입니다.

  1. 사용 루프 WHEN condition DO forms -clause :

    (loop for... 
         when (eq ...) do (return-from ...)) 
    
  2. 사용 루프 DO -clause 내부의 일반 WHEN -macro : 당신이 쓸 수있는 두 가지 방법이 있습니다

    (loop for... 
         do (when (eq ...) 
          (return-from ...))) 
    

코드에서 수정해야 할 몇 가지 사항이 있습니다. 리스프 사물의 이름을 지정할 때

  1. 오히려 (check-zero보다는 checkZero) CamelCase를보다 단어 사이에 대시를 사용합니다.
  2. 일반 숫자 비교에는 =을 사용하고 숫자가 0인지 확인하려면 ZEROP을 사용하십시오. EQ은 두 객체가 같은 객체인지 확인하는 데 사용됩니다.
  3. 당신은 내가 당신이 (VALUES-LIST (NTH ... (CAR ...)))으로 달성하기 위해 노력하고 무엇을 아주 확실하지 않다 RETURN
  4. 사용하여 루프에서 반환 할 수 있지만, 작동하지 않을 것. 단순한 값 목록 (예 : (1 2 3 4 5 6))을 단순히 반복하려는 경우 루프 FOR item IN list - 절을 사용해야합니다.

    (defun check-zero (list) 
        (loop for item in list 
         when (zerop item) do (return t))) 
    

    LOOP 또한 당신이 사용할 수있는 THEREIS condition -clause 있습니다 :

그래서 지금 당신이 뭔가를해야

(defun check-zero (list) 
    (loop for item in list 
     thereis (zerop item))) 

바로이 반환이 항목을 발견으로 그 ZEROP을 만족합니다. 그러나, 같은 것을 달성하는 쉬운 방법이 있습니다. MEMBER을 사용하여 목록에 0이 포함되어 있는지 확인할 수 있습니다.

(defun check-zero (list) 
    (member 0 list :test #'=)) 

CL-USER> (check-zero '(1 3 4 3 5 7)) 
NIL 
CL-USER> (check-zero '(1 3 4 3 0 5 7)) 
(0 5 7) 

일반화 된 부울을 반환합니다. 즉, NIL이 아닌 값은 Common Lisp에서 true로 간주됩니다.객체가 0 인 경우 확인하는 술어 기능 (ZEROP이)가 있기 때문에

, 당신은이에 대한 SOME 또는 MEMBER-IF을 사용할 수

(some #'zerop '(1 3 4 6 2 0 45 6 7)) ;=> T 
(member-if #'zerop '(1 3 4 6 2 0 45 6 7)) ;=> (0 45 6 7) 
+0

약간의 경고, 검사 할리스트가 합법적으로 비 숫자를 포함 할 수 있다면'equalp' (0과 0.0을 같게하기를 원할 경우) 또는'eql' (숫자 값과 숫자 타입을 같게하려면)을 사용하십시오. 왜냐하면'zerop 인수가 숫자가 아니고'='가능성이 높으면 오류를 표시해야합니다. – Vatine

관련 문제