2016-01-26 36 views
-2

我是新来的计划编程,我得到了这个任务,我只是无法找到如何正确工作。我应该用一个参数(一个数字)来定义一个过程。如果数字是正数,我希望返回1,如果数字为负,则返回-1;如果数字为0,则返回0,仅使用和/或。如果和cond是不允许的。我只得到#t#f返回,但你看到那不是我想要的。任何帮助或指针表示赞赏如何使用和/或代替if/cond?

的伎俩
+0

显示您的代码。到目前为止您尝试了哪些操作? – Rptx

回答

1
(define test 
    (lambda (n) 
     (or (and (< n 0) -1) 
      (and (= n 0) 0) 
      1))) 

部分的理解是,如果一切值为true,将返回它评估的最后一个项目,而将返回成功进行第一件事为真。另一部分意识到除#f之外的所有内容都被视为“真实”。

0

and改造在报告中看到,但不包括实际宏它基本上是这样的:

; only one argument 
(and a) ; ===> 
a 

; one of more 
(and a b ...) ; ==> 
(if a 
    (and b ...) 
    #f) 

所有参数都必须评估为正值并且最后的值是结果,其他#f。它短路,所以当有东西是#f其余的表达式永远不会被评估。

对于or是这样的:

(or a) ; ==> 
a 

(or a b ...) ; ==> 
(let ((a-value a)) 
    (if a-value 
     a-value 
     (or b ...))) 

不计算为#f的第一个参数被返回。如果所有的值都是#f,最后的#f将是结果。

因此,如果你想:

(if a b c)     ; ==> 

(let ((tmpa a))    
    (or (and atmpa b)   
     (and (not atmpa) c)) ; not part only important if b can be #f 

我用let防止评估同样的表情几次。例如。如果你有一个打印类似(begin (display "hello") #f)的东西,或者这是一个昂贵的计算,那么它是必要的,否则你可以用表达式替换变量。例如。最后将变成:

(or (and a b) 
    (and (not a) c)) 

那转换回没有临时变量成为:

(if (if a b #f) 
    (if a b #f) 
    (if (not a) C#f)) 

如果b为#f值,那么结果是#f因为最后if的。因此每次a为真b就是结果。每次它是假的,c就是答案。因此,

(if a b c) 

所以想象你想要返回列表中的第一个真正的值。

(define (first-true lst) 
    (and (not (null? lst)) 
     (car lst) 
     (first-true (cdr lst)))) 
3

,如果你看看下面的等价你能解决你的问题,当每个expj具有#f不同的值有效:自认为得到了数字的符号功能

(cond (test1 exp1)   (or (and test1 exp1) 
     (test2 exp2)    (and test2 exp2) 
     ...    ≡  ... 
     (testn expn)    (and testn expn) 
     (else expn+1))   expn+1) 

可以简单地用这种方式写出:

(define (sign x) 
    (cond ((> x 0) +1) 
     ((< x 0) -1) 
     (else 0))) 

在应用上述等价关系后,每个结果为整数,从#f不同,该功能变得等于溶液也在另一个答案提出:

(define (sign x) 
    (or (and (> x 0) +1) 
     (and (< x 0) -1) 
     0)) 

所以,它是上述等价的原因吗?这取决于and轮流评估其论点的事实;一旦它们中的一个是#f,它会通过返回#f来停止,否则返回它的最后的参数(并且这解释了单个分支(and testj expj));而or依次评估其论据;它们中的一个是而不是#f,它通过返回来停止,否则返回它的最后的参数(并且这解释了链(or (and ...) (and ...) ... expn+1))。

+0

只有当所有的expN都为真时,这种等价才是正确的。 –

+0

@DougCurrie,非常感谢,我已经纠正了答案。 – Renzo

相关问题