2

スキーム インターフェイスに慣れるための練習として、与えられたさまざまな文字列をチェックし、提供されたものに応じて適切な文字列を返す Dr. Racket (ただし MIT スキームと互換性があります) でプロシージャを作成しようとしています。私がこれまでに持っているのはこれです:

(define (conversation input)
    (cond ((eq? (or "hello Racket" "hi Racket" "what's up, Racket?" 
    "hey Racket" "what's happening, Racket?") input) "hey coder")
      (else "no hablo ingles.")))

※紐と紐の間はちょうど収まる程度です。インタプリタ内の 1 つの長いステートメントです。

望ましい効果は、次のものを入れた場合です。

(conversation "hello Racket")
(conversation "hi Racket")
(conversation "hey Racket")

それらはすべて同じ結果を返します。これは「hey coder」です。しかし、それは起こっていることではありません。「ちょっとコーダー」を返すのは (会話「こんにちはラケット」) だけです。残りはすべて「no hable ingles」を返します。言語の他の多くの側面と同様に、私はスキーム内の文字列に精通しているわけではありません。このコンテキストで機能する代替手段については知りませんが、問題が or ステートメント内にあることはかなり確信しています。解決策を調べてみましたが、このタイプの説明に当てはまるものは見つかりませんでした。動作するコードの代替案を知っている人はいますか?

4

2 に答える 2

3

or引数のリストを取り、その引数のいずれかが「真実」であるかどうかをチェックします (つまり、そうではありません#f)。もしそうなら、それは真実である最初の引数を返します。そうでない場合は、 を返します#f。したがって(or "string1" "string2" ...)、単純に「string1」を返します。したがって、指定された文字列が「hello Racket」と等しいかどうかを確認し、他のオプションを無視するだけです (「hello Racket」でも機能しないことに異議を唱えるかもしれませんが、それについては説明します)。あなたがしたいことはor、文字列だけでなく、全体の条件を に与えることです。したがって、次のようになります(or (eq? "string1" input) (eq? "string2" input) ...)

ただし、これも機能しません。なぜだめですか?eq?文字列の比較に使用する関数が間違っているためです。2 つの文字列がメモリ内の同じ場所に存在する場合にのみ true を返します。2 つの文字列が異なるメモリ位置にあるが、内容が同じである場合は、 を返します#f#fこれが、現在のコードが「hello Racket」を返す理由でもあります。使用する必要があるequal?のは、文字列の内容を比較する です。

これで動作するはずですが、少しぎこちなく、equal?可能なすべての文字列に対して の呼び出しを繰り返します。より良いアプローチは、有効な文字列でリストを作成し、member関数を使用して入力文字列がリストに含まれているかどうかを確認することです。

于 2012-12-21T16:02:55.967 に答える
2

member手順と可能なオプションのリストを使用して、意図した効果を得ることができます。

member等しい lst の最初の要素を見つけますか? そのような要素が存在する場合、その要素で始まる lst の末尾が返されます。それ以外の場合、結果は #f になります。

これが私が意味することです:

(define (conversation input)
  (cond ((member input '("hello Racket" "hi Racket" "what's up, Racket?"
                         "hey Racket" "what's happening, Racket?"))
         "hey coder")
        (else "no hablo ingles.")))
于 2012-12-21T16:46:13.467 に答える