문제

간단한 피보나치 함수를 확장하려고 하는데 각 항의 값을 두 번 이상 사용해야 합니다.그래서 나는 내가 사용할 것이라고 생각했습니다. let 가치를 붙잡기 위해.그러나 나는 그 기능에서 내가 생각해야 할 것을 얻지 못하고 있습니다.

여기 원본이 있습니다 fib 기능:

(define (fib n)
  (if (< n 2)
      n
      (+ (fib (- n 1)) (fib (- n 2)))))

여기에 같은 일을 하려는 나의 시도가 있습니다. let:

(define (fib-with-let n)
  (if (< n 2)
      0
      (let ((f1 (fib-with-let (- n 1)))
            (f2 (fib-with-let (- n 2))))
        (+ f1 f2))))

결과:

> (fib 10)
55
> (fib-with-let 10)
0

감사해요!

도움이 되었습니까?

해결책

오타를 냈습니다:

(if (< n 2)
    0
    ...)

네 말 뜻은 n.

다른 팁

기본 케이스를 잘못 입력했습니다.첫 번째 버전 : 라코 디스

하지만 후자의 버전에서는 다음과 같이 썼습니다. 라코 디스

그러므로 0n로 변경하세요.

당신의 let은 실제로 아무것도하지 않습니다. 여전히 모든 추가 계산을 수행하고 있습니다. f1(fib-with-let (- n 1))로 정의한다고해서 n-1의 fib를 다시 계산하지 않는다는 의미는 아닙니다. f2f1를 사용하지 않습니다 . f2f1 보도록 원한다면 let*를 사용할 것입니다. 그러나 이것은 실제로 원하는 것이 아닙니다.

이에 대한 증거로서 다음은 for fib(35)fib-with-let(35)의 실행 시간입니다. 라코 디스

추가 계산을 피하기 위해 정말로 원하는 것은 동적 프로그래밍 을 사용하고 재귀하는 것입니다. 상향식 .

원하는 것은 다음 코드입니다. 라코 디스

보시다시피 순진한 접근 방식이 걸리는 시간의 3 분의 1에 처음 150,000 개의 fib를 수행 할 수 있습니다. <시간>

let이 무엇을 더 잘 설명 할 수 있는지에 대해 혼란스러워 보이기 때문에

말할 때 : 라코 디스

말하고있는 것은 a를 1로, b를 2로하여 합산하는 것입니다. 대신 다음과 같이 말한 경우 : 라코 디스

무엇을 얻을 수 있을지 짐작할 수 있습니까? 아니 3. expand: unbound identifier in module in: a로 폭발 할 것입니다.

간단한 let에서는 과제가 서로 수 없습니다. 위의 내용을 작성하려면 let*를 사용해야합니다. 라코 디스

그렇게하면 예상 한 3 가지를 얻을 수 있습니다. let*는 기본적으로 다음으로 확장됩니다. 라코 디스 <시간>

당신이 Let 's로하고 있다고 생각한 것을 memoization 이라고합니다. 반복 할 필요가 없도록 중간 값을 저장하는 기술입니다. 하지만 그렇게하지 마십시오.

문제가 fib-with-let 함수의 오타이지만 가장 간단한 형식으로 let는 익명의 람다에 대해 "syntatic-sugar"이고 그 뒤에 인수가 평가되고 람 바로 전달 된 다음 평가되고최종 값이 반환되었습니다.그래서 라코 디스

다음처럼 보이도록 let없이 다시 작성 될 것입니다. 라코 디스

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