drracket如何在没有条件的情况下进行税收计算

时间:2014-03-14 03:21:56

标签: scheme racket

我是Scheme语言的新手。我想制作一个计算税收的程序。例如:

Price < 50   --------------------------------------->  Tax = %15

Price > 50 && Prize < 100  ------------------> Tax = %10

Price > 100  -------------------------------------->  Tax = %5 

有没有办法在不使用DrRacket&amp ;;中的if / switch / condition语句的情况下进行此计算。方案

3 个答案:

答案 0 :(得分:3)

由于这是家庭作业,所以不愿回答,但是......

首先,我将使用cond来编写此内容:

#lang racket
(require rackunit)

(define (tax-rate price)
  (cond [(< price  50) 0.15]
        [(< price 100) 0.10]
        [else          0.05]))

(check-equal? (tax-rate   1) 0.15)
(check-equal? (tax-rate  50) 0.10)
(check-equal? (tax-rate 100) 0.05)

接下来让我们考虑一下cond。它说,“如果价格<50,则税率为0.15 ,如果价格<100,则税率为0.10,,如果...... 。等等 ....“

请注意句子中的“”。确实听起来像cond是一种(or ...)表达式。第一个真正的东西“胜利”。

有了这个提示,也许你可以搞清楚吗?否则,扰流警报。




您可以使用condor重写and

(define (tax-rate2 price)
  (or (and (< price  50) 0.15)
      (and (< price 100) 0.10)
      0.05))

(check-equal? (tax-rate2   1) 0.15)
(check-equal? (tax-rate2  50) 0.10)
(check-equal? (tax-rate2 100) 0.05)

一般情况下,可以将cond重写为or提供除了最后一个以外的任何分支都不需要返回#f 。由于tax-rate永远不需要返回#f,因此可以在此处使用。

答案 1 :(得分:2)

假设您被允许使用min

(define (tax price)
  (/ (* price (- 15 (* 5 (min 2 (quotient price 50)))))
     100.0))
  • 对于值&lt; 50,(商价50)是0,所以税是(15-0 * 5)%= 15%。
  • 对于值> = 50且&lt; 100,(商价50)是1,所以税是(15-1 * 5)%所以10%。
  • 对于值> = 100,(商价50)为2或更高。由于我们不低于5%,我会使用min将结果减少到2,如果有必要,税收为(15-2 * 5)%= 5%。

测试:

> (tax 30)
4.5
> (tax 70)
7.0
> (tax 120)
6.0

并与使用条件的算法进行比较:

(for ((n 2000))
  (let ((tax1 (tax n))
        (tax2 (/ (* n (cond
                        ((< n 50) 15)                         
                        ((< n 100) 10)
                        (else 5)))
                 100.0)))
    (unless (= tax1 tax2)
      (printf "~a: fun= ~a   man= ~a \n" n tax1 tax2 ))))

与使用cond的公式没有区别(至少对于从0到1999的价格值)。

答案 2 :(得分:1)

确实有一种方法可以完全不使用任何条件,甚至是使用min等条件的预定义函数,但如果你是Scheme的新手,你就不会去喜欢它,它可能不是你想要的。诀窍是回到裸骨lambda演算,从中派生出来。

首先,将原语重新定义为true和false,作为返回第一个或第二个参数的函数:

(define TRUE  (lambda(t f) t))
(define FALSE (lambda(t f) f))

其次,将数字零定义为仅包含FALSE的列表(我们甚至可以避免使用列表基元,但是对于一个简单的例子,这将做),并定义两个函数来递增和递减数字:< / p>

(define zero (list FALSE))
(define (inc n) (cons TRUE n))
(define (dec n) (rest n))

定义一些数字:

(define one   (inc zero))
(define two   (inc one))
(define three (inc two))

因此,非zero的任何(正数)数字的第一个元素为TRUE,而FALSEzero。您可以使用此信息来定义一个函数,该函数将数字和两个函数作为参数,如果数字为正,则应用第一个函数,否则应用第二个函数:

(define (if-positive n proc-true proc-false)
  (((first n)
    proc-true
    proc-false)))

;; TESTS
(if-positive three (lambda() 'positive) (lambda() 'zero)) ; -> 'positive
(if-positive zero  (lambda() 'positive) (lambda() 'zero)) ; -> 'zero

现在,我们可以创建一个函数,它接受两个数字和两个过程,从每个数字递归地减去1,如果第一个数字首先达到0,则应用第一个过程,但如果第二个数字达到0则首先应用第二个过程过程:

(define (if-greater n1 n2 proc-true proc-false)
  (if-positive 
   n1 
   (lambda()(if-positive 
        n2
        (lambda()(if-greater (dec n1) (dec n2) proc-true proc-false))
        proc-true))
   proc-false))

;; TESTS
(if-greater three two (lambda() 0.15) (lambda() 0.1)) ; -> 0.15
(if-greater one   two (lambda() 0.1)  (lambda() 0.05)) ; -> 0.05

现在你需要做的就是定义数字100和50,你很高兴。当然这是非常不切实际的,但这就是你不使用if所得到的。 (请注意,通过使用基数2而不是基数1可以使其更加实用,但对于此示例,这是一个细节。)

更多信息here例如,但对新手来说可能有点苛刻。