简体   繁体   English

甚至? 计划中的功能(Racket博士)

[英]Even? function in Scheme (Dr. Racket)

I'm trying to write a program in Scheme to compute the result of the power function using the fast power algorithm/recursion. 我正在尝试在Scheme中编写一个程序,以使用快速幂算法/递归来计算幂函数的结果。 The algorithm should be correct, but somewhere my syntax is off. 该算法应该是正确的,但是我的语法不正确。 The program compiles, but when I input a base and exp to test, Dr. Racket freezes up and runs out of memory. 该程序可以编译,但是当我输入一个基数和exp进行测试时,Racket博士冻结并耗尽了内存。 Having a difficult time locating online examples for how the (even?) function should appear in scheme code. 很难找到在线示例,以了解(even?)函数应如何出现在方案代码中。 I think this might be throwing my syntax off. 我认为这可能会拖累我的语法。 New to scheme so any help would be much appreciated. 计划的新手,所以将不胜感激。

(define (powFun base exp)
    (if ( = exp 0)                       //base case
     1                                     
       (even? exp                        //if exp is even
          (*
            (powFun base ( / exp 2))
            (powFun base ( / exp 2))
          )

       (*
          (powFun base (- exp 1) )      // else if exp is odd
           base 
       )
     )
  )

)

You seem to be using even? 您似乎正在使用even? as if it was some kind of macro that behaves like if . 好像是某种类似于if的宏。 But even? 但是, even? is a regular function that takes one argument, so you should have written (even? exp) and not (even? exp evaluate-if-even evaluate-if-not-even) . 是一个带一个参数的常规函数​​,因此您应该编写(even? exp)而不是(even? exp evaluate-if-even evaluate-if-not-even) That means the return value of even? 那意味着even?的返回值even? needs its own if expression: 需要自己的if表达式:

(if base-case
   1
   (if (even? exp)
       evaluate-if-even
       evaluate-if-not-even))

...which means you should be using cond instead. ...这意味着您应该改用cond

Or, you could define a macro that works the way you thought even? 或者,您可以定义一个宏以您认为的方式工作even? worked. 工作了。 Let's call it if-even : 让我们称之为if-even

(define-syntax if-even
    (syntax-rules ()
       ((_ n evaluate-if-even evaluate-if-not-even)
        (if (even? n) evaluate-if-even evaluate-if-not-even))))

Then replace even? 然后替换even? in your original program with if-even . 在您的原始程序中使用if-even Correcting your use of even? 更正您使用even? and then switching to cond instead of if is the better option, though. 然后切换到cond而不是if是更好的选择。

even? is not similar to if - you use it to test whether one number is even. if -您可以使用它来测试一个数字是否为偶数。
It does not have "branches": 它没有“分支”:

> (even? 2)
#t
> (even? 2 "even" "odd")
. . ..\..\Program Files (x86)\Racket\share\pkgs\drracket\drracket\private\rep.rkt:1088:24: even?: arity mismatch;
 the expected number of arguments does not match the given number
  expected: 1
  given: 3
  arguments...:
   2
   "even"
   "odd"

You can use it as a test in a conditional: 您可以将其用作条件中的测试:

> (if (even? 2) "even" "odd")
"even"

If you want to test several conditions, it's convenient to use cond instead of if : 如果要测试多个条件,可以使用cond代替if

> (define x 3)
> (cond ((= x 1) "one")
         ((even? x) "even")
         (else "odd"))
"odd"

But that's not the reason for DrRacket "freezing". 但这不是DrRacket“冻结”的原因。

The reason for that is that the division is not an integer division but actually produces an exact fractional result: 这样做的原因是该除法不是整数除法,但实际上会产生精确的分数结果:

> (/ 1 2)
1/2
> (/ (/ 1 2) 2)
1/4
> (/ (/ (/ 1 2) 2) 2)
1/8

so you will never reach the terminating case. 因此,您将永远无法达成最终目标。

You should use the quotient procedure: 您应该使用quotient过程:

> (quotient 3 2)
1
> (quotient 2 2)
1
> (quotient 1 2)
0

Making use of the sqr procedure and changing your brackets from "C style" to "Scheme style", it might look like this: 利用sqr过程并将方括号从“ C样式”更改为“方案样式”,它可能看起来像这样:

(define (powFun base exp)
    (if (= exp 0) 
        1                                     
       (if (even? exp)
           (sqr (powFun base (quotient exp 2)))
           (* (powFun base (- exp 1)) base))))

Or 要么

(define (powFun base exp)
    (cond ((= exp 0) 1)                                    
          ((even? exp) (sqr (powFun base (quotient exp 2))))
          (else (* (powFun base (- exp 1)) base))))

> (powFun 2 3)
8
> (powFun 2 0)
1
> (powFun 2 300)
2037035976334486086268445688409378161051468393665936250636140449354381299763336706183397376

Side note: the interaction window is extremely useful for testing small parts of code when you're looking for a problem. 注意事项:交互窗口对于查找问题时的少量代码测试非常有用。

if can only take max 2 clauses, then and else without keyword. if只能拿最多2项条款, thenelse没有的关键字。 In this situation, you can either use nested if or cond . 在这种情况下,您可以使用嵌套的ifcond Following is an example of cond : 以下是cond的示例:

(cond ((= expr 0) 1)
      ((even? exp) #| do even ... |#)
      (else #| do odd |#))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM