문제

내가 다음 구조의 해석 컴퓨터 프로그램 고 시도하는 동안을 해결하 Ex1.3 에 도착했을 다음과 같은 코드를 처음으로 시도:

(define (sumsq a b c)(
(define highest (if (> (if (> a b) a b) (if (> a c) a c)) (if (> a b) a b) (if (> a c) a c)))
(define second_h (if (> (if (> a b) b a) (if (> a c) c a)) (if (> a b) b a) (if (> a c) c a)))
(+ (* highest highest) (* second_h second_h)))

그것은 작동하지 않고 그리고 해결책을 발견에서 그들을 SICP Wiki

;; ex 1.3
;; implemented using only techniques covered to this point

(define (square x) (* x x))

(define (sum-of-squares x y)
  (+ (square x) (square y)))

(define (largest-two-of-three x y z)
  (if (>= x y)
      (sum-of-squares x (if (>= y z) y z))
      (sum-of-squares y (if (>= x z) x z))))

차이었을 사용하여 여러 문에서 변수를 정의한 다음 합계,사각형하는 동안 올바른 방법으로 정의하는 각 라인으로 기능한다.

는 기능을 계획 중이너?또는 놓치지 않았다 모든 것은?

도움이 되었습니까?

해결책

당신이 쓴 것 (추가 Paren)은 다음과 같습니다.

(define (sumsq a b c)
  (define highest
    (if (> (if (> a b) a b)
           (if (> a c) a c))
      (if (> a b) a b)
      (if (> a c) a c)))
  (define second_h
    (if (> (if (> a b) b a)
           (if (> a c) c a))
      (if (> a b) b a)
      (if (> a c) c a)))
  (+ (* highest highest) (* second_h second_h)))

그들의 솔루션은 별도의 제곱과 제곱의 합계를 별도의 기능으로 수행하지만, 그것이 중요한 것이라고 생각하지 않습니다. 글을 쓰지 않습니다 (+ (* a a) (* b b)) ~ 할 것이다 당신이 계산하는 두 값의 이름을 지정하지 못하도록 멈추면 마지막에 하나의 큰 표현으로 함수를 쓸 수 있지만 지금은 더 큰 것들이 있습니다.

나는 당신이 가지고있는 문제는 당신의 (만약 ...) 표현이 너무 크다는 것입니다. 여러 번 나타나는 두 가지 패턴이 있습니다. (if (> a b) a b) 그리고 (if (> a b) b a). 이것들은 최대 및 최소 함수이므로 다음과 같이 정의하는 것이 유용합니다.

(define (min a b) (if (< a b) a b))
(define (max a b) (if (< a b) b a))

이렇게하면 솔루션을 다음과 같이 다시 작성할 수 있습니다.

(define (sumsq a b c)
  (define highest
    (if (> (max a b) (max a c))
      (max a b)
      (max a c)))
  (define second_h
    (if (> (min a b) (min a c))
      (min a b)
      (min a c)))
  (+ (* highest highest) (* second_h second_h)))

다시 단순화하면 다음과 같습니다.

(define (sumsq a b c)
  (define highest
    (max (max a b) (max a c)))
  (define second_h
    (max (min a b) (min a c)))
  (+ (* highest highest) (* second_h second_h)))

이 글쓰기가 훨씬 더 쉬운 방법에 주목하십시오. (max (max a b) (max a c)) 분명히 최대 값입니다 a b 그리고 c, 실제로 다시 작성할 수 있습니다 (max (max a b) c). 보고 있습니다 second_h, 그러나 그것이 옳다는 것은 분명하지 않습니다. 언제 일어날 것인가 a 세 값 중 가장 작습니까?

그들이 솔루션에서 사용하는 트릭은 먼저 비교하는 것입니다. x 그리고 y. 만약에 x < y, 당신은 그것을 알고 있습니다 y 세 가지 중 가장 작지 않으므로 가장 높거나 두 번째로 최고입니다. 사용하려는 다른 숫자는 더 높습니다. x 그리고 z,이 두 가지 중 낮은 사람은 당신이 무시하고자하는 세 가지 중 가장 작은 것입니다. 비슷한 논리가있을 때 적용됩니다 y < x.

다른 팁

당신이 사용해야 하는 적절한 들여쓰기하고 줄 바꿈을 개요를 얻을 통해 귀하의 프로그램으로 흐릅니다.귀하의 첫 번째 제안을 읽은 다음과 같다:

(define (sumsq a b c)
  ((define highest 
     (if (> (if (> a b) a b)
            (if (> a c) a c))
         (if (> a b) a b)
         (if (> a c) a c)))
   (define second-h
     (if (> (if (> a b) b a)
            (if (> a c) c a))
         (if (> a b) b a)
         (if (> a c) c a)))
   (+ (* highest highest)
      (* second-h second-h)))

첫번째 것을 사항:괄호가 일치하지 않;거기에 하나 더 많은 열었다 닫힙니다.신중 검사는 하나 괄호에서 두 번째 라인은 잘못된 것입니다.이것은,부수적으로,하나만 매달려의 끝에서 당신의 첫 번째 줄 수 있습니다.나는 것을 짐작할 때는 시도를 평가하이,아무 일도로 독자 기다렸다가 끝날의 문입니다.

적절한 압은 매우 중요합니다.내가 생각하는 SICP 지 않는 명시적으로 그것을 설명하지만,예를은 일반적으로 수행하는 이 방법입니다.내가 찾는 스타일 가이드 .

두 번째 관찰당신은 자신을 반복을 많이합니다.에서 모든 사람들 중첩 if 문까지 여부를 당신이 정말로 가지고 오른쪽의 값이다.보 해결책을 발견하시는 방법이 매우 단순화될 수 있습니다.

당신도를 깨고 복잡성을 제공하여 subresults 이름입니다.깨는 복잡성은 좋지만,그것은 일반적으로 더 나은 이름은 결과가 아니지만,그 개념이 있습니다.생각이 무엇을 하는지 이름을 지정한 다음 이러한 활동입니다.사람들은 함수,그리고 그들의 언어는 당신이 마지막으로 거는 이제껏 당신의 문제를 해결합니다.

계획의 아이디어 중 하나는입니다 bottom-up programming 각 개념 작업에 대한 함수를 만듭니다. 이것이 많은 기능 프로그래밍 언어에서 권장되는 접근법입니다.

이 접근법을 통해 인수에 대해 하나의 논리적 작업을 구현하는 많은 작은 기능으로 끝납니다. 그렇게하면 코드가 훨씬 더 모듈화되고 깨끗합니다.

솔루션은이 양식을 가졌습니다. (정의 (func param) (정의 ...) (정의 ...))

그러나이 형태가 필요하다 : (정의 (func param) 본체)

본문은 기능의 구현입니다 ... 그것이하는 일, 반환하는 것입니다. 당신의 몸은 단지 더 많은 정의였습니다. 따라서 Scheme 통역사가 솔루션이 허용되지 않은 이유를 설명합니다.

"체계 기능은 1 라이너입니까?" 다음과 같이 보이는 "시작"양식을 조사해야합니다. (시작 (+ 1 1) (+ 2 2)) => 4

위의 예에서 (+ 1 1)의 결과는 방금 던져 지므로 시작이 부작용이있을 때만 시작되는 것을 볼 수 있습니다.

당신은 계획의 일부 (특히 Let and Lambda)가 그들의 몸 주위에 암시 적 시작을 가지고 있음을 알고 있어야합니다. 그래서 이것은 유효합니다.

  (let ((x 1))
    (+ 1 1)
    (+ 2 2))

시작 없이도. 이로 인해 코드를 더 간단하게 작성합니다.

마지막으로, 학습 계획을 계속할 때 항상 시작과 부작용없이 무언가를 할 수있는 방법을 찾으십시오. 특히 대부분의 계획서의 처음 몇 장에서 "나는 그 변수를 설정하고 싶다면 이것을하고 싶다." 그것은 계획 방식입니다. 부작용에는 전혀 잘못된 것이 없지만, 그 중에 많이 사용하면 실제로 가장 잘 작동하는 방식으로 프로그래밍 체계가 아니라는 것을 의미합니다.

연습 1.3은 세 개의 숫자를 인수로 취하는 절차를 정의하고 두 개의 더 큰 숫자의 제곱 합을 반환하도록 요청합니다. 내장 체계 절차를 사용하는 것과 같은 절차를 쉽게 정의 할 수 있습니다. square, max, 그리고 min, 그러나 우리는이 시점 에서이 절차를 아직 접하지 않았으므로 아직도 정의 할 것입니다.

(define (square x)
   (* x x))

(define (max x y)
   (if (> x y) x y))

(define (min x y)
   (if (< x y) x y))

(define (sum-of-highest-squares x y z)
   (+ (square (max x y))
      (square (max (min x y) z))))

그만큼 sum-of-highest-squares 절차는 최대 x와 y의 제곱을 추가하여 작동합니다 (이 두 가지의 최대는 3 개 중 가장 낮은 것부터 제거)와 나머지 2 개 (최소 x 및 y)의 제곱이 제거됩니다. 첫 번째 단계에서 남은 값은 무엇보다) 및 z.

참고 : 이것은 내 블로그 게시물에서 나온 것입니다 SICP 운동 1.1-1.5. 다른 많은 SICP 솔루션으로 이동할 링크도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top