1

X と Y の 2 つの整数を取り、X/Y + (X-1)/(Y-1) + ...いずれかの数値が 0 になるまで再帰的に加算することになっている Scheme の関数を作成しています。

たとえば、4 と 3 を取ります。

4/3 + 3/2 + 2/1 = 29/6

正しく動作していない私の機能は次のとおりです。

(define changingFractions (lambda (X Y)
    (cond 
        ( ((> X 0) and (> Y 0)) (+ (/ X Y) (changingFunctions((- X 1) (- Y 1)))))
        ( ((= X 0) or (= Y 0)) 0)
    )
))

編集:コメントに記載されている問題を修正するためにコードを変更し、 と の場所を変更しましorand

(define changingFractions (lambda (X Y)
    (cond 
        ( (and (> X 0) (> Y 0)) (+ (/ X Y) (changingFunctions (- X 1) (- Y 1) )))
        ( (or (= X 0) (= Y 0)) 0)
    )
))

残念ながら、まだエラーが発生しています。

4

2 に答える 2

5

そこにいくつかの問題があります:

  • (define (func-name arg1 arg2 ...) func-body)ラムダ関数を変数に割り当てるのではなく、構文で関数を定義する必要があります。
  • andとは、(ではなく)orフォームの最初の要素として使用することで、関数のように使用されます。引数の間にそれらを置くことによってではありません。(and x y)(x and y)
  • 再帰呼び出しの関数パラメーターの周りに余分な括弧のセットがありchangingFunctions、名前がchangingFractions.
  • エラーではありませんが、閉じ括弧を独自の行に配置しないでください。
  • changing-fractionsLisp での命名規則は、キャメルケースではなく (ではなく)ダッシュを使用することchangingFractionsです。

それらが修正された場合:

(define (changing-fractions x y)
  (cond 
   ((and (> x 0) (> y 0)) (+ (/ x y) (changing-fractions (- x 1) (- y 1))))
   ((or (= x 0) (= y 0)) 0)))

condただし、を anifに変更して、より明確にすることができます。

(define (changing-fractions x y)
  (if (and (> x 0) (> y 0))
      (+ (/ x y) (changing-fractions (- x 1) (- y 1)))
      0))
于 2016-02-04T16:01:32.453 に答える
1

私は個人的にこの実装が好きです。ここで提供される他の回答とは異なり、適切なテールコールがあります。

(define (changing-fractions x y (z 0))
  (cond ((zero? x) z)
        ((zero? y) z)
        (else (changing-fractions (sub1 x) (sub1 y) (+ z (/ x y))))))

(changing-fractions 4 3) ; => 4 5/6

トリックは、zデフォルトで0. このアキュムレータを使用すると、再帰するたびに分数の合計を繰り返し作成できchanging-fractionsます。これを、@jkliski の回答で再帰ごとに追加される追加のスタック フレームと比較してください。

; changing-fractions not in tail position...
(+ (/ x y) (changing-fractions (- x 1) (- y 1)))
于 2016-02-05T13:54:26.173 に答える