2

为了让自己更熟悉方案接口,我尝试在 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.")))

*字符串之间的空间正好适合这里。这是解释器中的一个长语句。

想要的效果是,如果我输入:

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

它们都将返回相同的结果,即“嘿 coder”。然而,事实并非如此。唯一返回“hey coder”的是(对话“hello Racket”)。其余的都返回“没有能力”。与该语言的许多其他方面一样,我对方案中的字符串不太了解。我相当确定问题出在 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?是用于比较字符串的错误函数。仅当两个字符串位于内存中的同一位置时,它才返回 true。如果两个字符串位于不同的内存位置,但内容相同,则返回#f. 这也是您当前代码返回#f“hello Racket”的原因。您应该使用的是equal?,它比较字符串的内容。

这现在应该可以工作了,但它有点笨拙 -equal?对每个可能的字符串重复调用。member更好的方法是使用有效字符串创建一个列表,然后使用该函数检查输入字符串是否包含在列表中。

于 2012-12-21T16:02:55.967 回答
2

您可以使用该member过程和可能的选项列表来实现您想要的效果:

member找到 lst 的第一个相等的元素?to v. 如果存在这样的元素,则返回从该元素开始的 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 回答