2013-05-07 2 views
-3

집합에서 모든 홀수를 더하는 clisp에서 함수를 만들어야합니다. 예를 들어 하위 집합 (2,8)의 경우 결과는 15 (3 + 5 + 7)입니다.). 어떤 제안? 나는 a가 집합의 시작이고 b가 그것의 끝인 곳에서 이와 같은 것을 가지고있다.하위 집합에서 홀수를 더하는 Lisp 함수

(defun add (a b) 
(if(and(< a x) (> b x)) 
    (if(even(x)) 
     ((setq (x (+a 1))) (+ x 2)) 
     ((setq(x a)) (+ x 2)) 
      ))) 

편집 :

(defun add (a b) 
(if(and(< a x) (> b x)) 
    (if(evenp x)) 
     ((setq (x (+a 1)) 
      (loop for x from a to b do (+ x 2)))) 
     ((setq(x a)) (+ x 2) 
      (loop for x from a to b do (+ x 2))) 
       )) 
+0

시작. – Barmar

+0

글쎄, 알고리즘이 작동해야하는 방법을 알았어. 그냥 lisp로 구현하는 법을 모르겠다. – user2167174

+0

시도한 것을 보여 주면서, 우리는 당신을 위해 숙제를하러 온 것이 아니다. – Barmar

답변

0

나는 그것이 실용적 프로그램을 사용하는 것입니다 볼 수있는 간단한 방법.

(range 8 :min 2) => (2 3 4 5 6 7) 

을 다음과 필터 제거-IF-하지 :

(defun range (max &key (min 0) (step 1)) 
     (loop for n from min below max by step 
     collect n)) 

이처럼 간격을 생성하는 범위의 기능을 사용할 수 있습니다

(remove-if-not #'oddp (range 8 :min 2)) => (3 5 7) 

및 결과에 추가 적용 :

(apply #'+ (remove-if-not #'oddp (range 8 :min 2))) => 15 

당신도 기능에 이상을 포장 할 수 있습니다 :이 LOOP 함께 할

(defun add (a b) 
     (apply #'+ (remove-if-not #'oddp (range b :min a)))) 
+1

APPLY를 사용하지 말고 REDUCE를 사용하십시오. –

+2

RANGE의 사용법은 실제로 전체 목록을 만들기 때문에 Common Lisp에서는 그리 좋지 않습니다. 게으른 언어에서는 이것이 사실이 아닐 수도 있습니다. –

2

가장 직접적인 방법입니다. 반복을 위해, 당신은 또한 DO를 사용할 수

(defun sum-odds (start end) 
    (loop for i from start to end 
     when (oddp i) sum i)) 

(sum-odds 2 8) 
=> 15 

,하지만 당신은 모든 작동 방식에 대한 좀 더 명시해야한다 (당신은 더 많은 옵션을 사용할 수 있습니다) : :이 LOOP 솔루션은 매우 간단

(defun sum-odds2 (begin end) 
    (do ((sum 0) 
     (i begin (1+ i))) 
     ((= i end) sum) 
    (when (oddp i) 
     (incf sum i)))) 

(sum-odds2 2 8) 
=> 15 

다른 답변에서 제안하는 것처럼 정수 범위 (가비지 수집 할 일련의 중간 목록을 만드는 목록)를 만드는 목록을 만드는 솔루션을 사용하는 경우 목록을 몇 번 통과해야하는지 고려해야합니다 그것을 한 번 이상 통과 할 이유 없음). 내가 보통의 주특기를하기 위하여려고하고 코드에 넣어

(defun sum-odds3 (list) 
    (reduce '+ list 
      :key (lambda (n) 
       (if (oddp n) 
        n 
        0)))) 

(sum-odds3 '(2 3 4 5 6 7 8)) 
=> 15 
1

: 당신은 홀수 자신처럼, 심지어 숫자 0처럼 보이게 만드는 :key 인수 목록의 요소 합계를 REDUCE을 사용할 수 있습니다 - 재검토 모자,하지만 두 번째 시도의 형식을 올바르게 지정했다면 점진적인 접근 방식을 취하기에는 너무 많은 문제가 있습니다. 앉아서이 코드의 의도를 설명해야합니다.

특히 x은 어떻게됩니까? 그것은 매번 다시 설정하는 글로벌 바인딩이 될 것인가 아니면 지역 바인딩을 정의한다는 의미 였고 실수로 변수를 필요로한다는 사실을 잊어 버렸습니다. 당신은 그걸 setq으로 무엇을하려하고 있습니까? 그리고 그걸로 무엇을하려하고 있습니까? (서면으로, 아무것도하지 마십시오) loops?


첫번째로, 친절 format your code properly [일시적으로 코드 리뷰 모자를 만났]. 그것은 작은 것이지만, 꽤 가독성을 높입니다.

(defun add (a b) 
    (if (and (< a x) (> b x)) 
    (if (evenp x)) 
    ((setq (x (+ a 1)) 
      (loop for x from a to b do (+ x 2)))) 
    ((setq (x a)) (+ x 2) 
     (loop for x from a to b do (+ x 2))))) 

그리고 적절한 들여 쓰기 수준

는 꽤 많은 오류는 바로 당신을 이을합니다. 그 위에 if

  • 첫째는, 거기에 세 가지 조항 (어떤 이유로 ifsetq들)을 가지고있다.
  • 둘째, 두 번째 if에는 절이 없으며 테스트에 불과합니다. 어떤 의미가 없음을 의미합니다.
  • 셋째, if 본문에서 매우 기묘하게 명명 된 기능을 호출하는 것입니다. 나는 ((setq (x a)) (+ x 2) (loop for x from a to b do (+ x 2)))이 어떤 의미가 아니라는 것을 보장하고자합니다. 이는 (+ x 2)(loop ...) 인수에 대해 (setq (x a)) 함수를 호출하기 때문입니다.
  • 넷째, 서로 다른 두 가지 잘못된 방법으로 setq을 호출합니다. (setq (x (+ a 1))x(+ a 1)에 호출 한 결과를 NIL으로 설정하려고 시도하고 있습니다. (setq (x a)) (+ x 2)xa에 호출 한 결과를 NIL으로 설정하고 (+ x 2)을 평가하고 버리는 결과를 설정하려고합니다.
0

구문 문제를 해결해야만 알고리즘 문제가 발생합니다. 당신은 분명히 솔루션을 추측하고 아직 추측을 컴파일하지 않았습니다. 코드가 컴파일되지 않고 실행되지 않습니다. 당신은 사소한 탐험을 허용하기 때문에 리스프와 유사한 언어를 정확하게 연구하고 있습니다. 그래서 탐험해라. 루프 2를 추가하고 범위의 끝을지나 때까지, 총에 그들 모두를 추가하는 최초의 홀수의 번호 또는 범위의 시작과 동일한와

(defun add (a b) 
    (cond ((evenp a) (add (+ a 1) b)) 
     ((> a b) 0) 
     (t   (+ a (add (+ a 2) b)))))