-1

例: (reverse-list (list 1 2 3 4)) => 4321 注: string->num または num->string または reverse は使用できません。

そのため、リストが消費され、逆数が作成されます (リストではなくなります)。

再帰ロジックに問題があります。

(define (reverse-list lofd)
 (cond [(empty? lofd) empty]
       [else (+ (* (exp 10 (something that starts at 0 and adds one extra everytime))
                   (first lofd))
                (convert-to-decimal (rest lofd)))]))

私のコードが開始され、最初の数値が num1*10^0 に変換され、再帰される数値が追加されます。

私が問題を抱えているのは、再帰で指数が10 ^ 0になり、リストの長さが1を引くまで1、2、3になるようにするにはどうすればよいですか? また、私のロジック/テンプレートは正しいですか? ありがとうございました!

4

3 に答える 3

4

強い提案:リスト構造の設計レシピに従ってください。この問題はあなたにとって十分に目新しいものであり、簡単には理解できないでしょう。デザイン レシピの手順で実行できる追加のサポートが必要です。

この特定のケースでは、この問題の解決策がすぐに明らかではないため、役立つ一連の優れた例 (テスト ケース) が本当に必要です。この関数はリストからリストへの変換ではないため、トリッキーです。リストから数値への変換であるため、ばかげた間違いを見つけるのに役立つ強力なスイートが必要です。

たとえば、何をすべきですか?

(check-expect (reverse-list empty) <fill-me-in>)

なれ?また、空のリストも考慮する必要がありますか? 入力がおかしくないですか?それは理にかなっていますか?コントラクトは、入力として空のリストを処理する必要があると述べていますか?それとも、空でないリストのみを受け入れることを保証できますか? これは、事前に解決する必要がある種類のものです。コントラクトのタイプが原因で、現在コードにあるものは確かに正しいとは言えません...まあ、正式にコントラクトを表現していませんが、一度表現すると、基本ケースが異なる必要があることがわかりますあなたが今まで書いてきたことよりも

Design Recipe に関する引用リンクでは、パート 5 が重要です。関数のテンプレートを取得したら、自然再帰がどのようなものを計算しているかを理解する必要があります。具体的なテスト ケースを使用してください。あなたのコードを見ると、あなたが書いたコードは「自然再帰は何を計算しますか?」という質問を考慮していないように見えるため、このステップをスキップしたようです。


具体的には、次のようにします。

(reverse-list (list 1 2 3 4))

答えは何ですか?あなたはそれを自分で言いました:

(reverse-list (list 1 2 3 4))   ==>   4321

自然再帰がどうなるかを考えてみましょう:

(reverse-list (list 2 3 4))

これの価値は何ですか?私たちはそれがなければならないことを知っています

(reverse-list (list 2 3 4))     ==>   432

それを理解したら、自問してみてください: 自然再帰の値は、元の質問の答えと何らかの関係がありますか?

解決しようとしていることを考えると:

(reverse-list (list 1 2 3 4))   ===>   4321

ピース1(リストの最初の部分) と432(自然再帰からの) があります。まとめ1432、何らかの方法で取得でき4321ますか?


いくつかの例についてこれを繰り返します。そして、少数とは、複数を意味します。:) これらの例に対して具体的にこれを行うと、再帰ケースのコードがどうあるべきかを理解するために、パターン マッチングと一般化を行う脳がはるかにうまく機能するようになります。

つまり、具体的なケースの正しい答えを得る方法を理解するための十分な演習を行ったら、具体的な値で行っていたことをプログラムの元の用語に戻して表現できるかどうかを確認します。たとえば、次のことがわかった場合:

we want to get 4321 out of 1 and 432:
    => 1 + 10 * 432

...  other examples you worked out...

これらを接頭辞表記で再表現しましょう。

we want to get 4321 out of 1 and 432:
    => (+ 1 (* 10 432))

...  other examples you worked out...

どの部分が変化していますか?どの部分が同じままですか?最初の変化部分は何の略ですか?2番目の変更部分は何の略ですか? あれは:

we want to get 4321 out of 1 and 432:
    => (+ 1 (* 10 432))

...  other examples you worked out ...

we want to get (reverse-list lst) out of (first lst) and (reverse-list (rest lst))
    ==> ???

パターンを確認したら、再帰的な場合に必要なコードを理解できたことになります。ただし、ここでは一連の例が本当に必要であることに注意してください。1 つの特定の例を一般化しようとするだけでは、脳がパターンを認識するのに十分ではありません。あなたの脳は、パターンを認識し始めるために、複数の例を繰り返し実行する必要があります。

于 2013-03-19T03:47:15.117 に答える
1

これはスキームのソリューションです。null? 、 car 、 cdr など、歴史的に重要なものを使用していますが、「ラケットの学習」語彙には含まれていません。多分それはアプローチを説明するでしょう。

(define (list->reverse-number l)
  (if (null? l)
      0
      (+ (car l) (* 10 (list->reverse-number (cdr l)))))

どうしても使いexptたい場合は、次のようなことを試してみてください (named-let を使用しますが、これはあなたのレベルを超えている可能性があります)。

(define (list->reverse-number l)
  (let reversing ((l l) (n 0))
    (if (null? l)
        0
        (+ (* (expt 10 n) (car l))
           (reversing (cdr l) (+ n 1))))))

しかし、上記が機能するかどうかはわかりません。実際、これも機能します。

于 2013-03-19T06:15:28.187 に答える
1

入力リスト以外に、別のパラメーターを渡す必要があります。必要に応じて、これが機能するように新しいヘルパー プロシージャ (または内部プロシージャ、名前付きletなど) を作成します。2 つのパラメーターは、リスト内の現在の位置と現在の指数 10 を追跡します。これらの行に沿った何か:

(define (reverse-list lofd n)
  (cond [(empty? lofd) ; what do we return if the list is empty?
         <???>]        ; not the empty list! we're building a number
        [else          ; otherwise add this term, taking the
         (<???> <???>  ; current element times current 10^n and
            (reverse-list <???> <???>))])) ; advance recursion over lofd and n

この初期値でプロシージャを呼び出します。

(reverse-list (list 1 2 3 4) 0)
=> 4321
于 2013-03-19T03:41:02.167 に答える