在Racket中编写出队功能

时间:2012-10-02 16:50:43

标签: racket

我尝试进行队列练习,我打算为给定队列编写enqueue,dequeue,top和size函数。出队功能目前给我带来了麻烦。出列函数的期望结果如下所示。

(define q (make-queue))
(enqueue q 10)
(enqueue q 20)
(enqueue q 30)
(dequeue q)
10
(dequeue q)
20
(dequeue q)

我的代码目前看起来像这样

(module queue racket
  (provide make-queue enqueue dequeue top size) ;queue-tests)
  (struct queue (front back size) #:mutable #:transparent)

    (define (make-queue) (queue null null 0))

(define (enqueue q elt)
    (set-queue-size! q (+ (queue-size q) 1))
    (set-queue-back! q (cons elt (queue-back q)))
    )

(define (dequeue q)
    (cond  ((eq? (queue-size q) 0) null)
           ((null? (queue-front q))
           (begin
           (set-queue-front! q (cdr (reverse (queue-back q))))
           (set-queue-back! q null)
           (set-queue-size! q (- (queue-size q) 1))))
           (#t 
           (begin
           (set-queue-front! q (cdr (queue-front q)))
           (set-queue-size! q (- (queue-size q) 1))))))

  (define (top q)
    (cond ((eq? (queue-size q) 0) null)
          ((null? (queue-front q)) (last (queue-back q)))
          (#t (car (queue-front q)))))

  (define (size q)
    (queue-size q))

请问出队功能有什么问题?我对Racket相当新,我将不胜感激。

2 个答案:

答案 0 :(得分:1)

你的问题表明你有点在海上;特别是,你没有理解你理解构成你的程序的部分。我想我会引导你在测试排队和出队功能的模块中编写测试用例

如果我误解了你的情况,请道歉!

答案 1 :(得分:1)

做一个小得多的测试用例。

(define q (make-queue))
(enqueue q "hi")
(dequeue q)

更重要的是,不要将测试用例视为 printf 语句。您真正想要做的是在特定时间点写出您知道队列状态需要的内容。并且您希望使用check-equal?以真实代码表达这些期望。写出每个步骤后队列应该是什么,然后使用 check-equal?来准确捕捉你的期望和代码分歧的位置。

否则,您的测试用例实际上并不是"测试"除了没有崩溃之外的任何事情。您希望从测试用例中获得更多:您希望他们测试行为

以下是两个测试用例示例:

(require rackunit)
;; ..  after your definitions
(let ()
   (define q (make-queue))
   (check-equal? q (queue null null 0)))

(let ()
   (define q (make-queue))
   (enqueue q 42)
   (check-equal? q (queue null '(42) 0)))

注意,我在第二个测试用例中犯了一个故意的错误!请注意,它错误地期望队列大小为零。所以修复它。 :)

dequeue 进行同样的测试。

其他低级别细节:

我不明白第三种情况。我希望在那里看到 else ,但我没有,所以我不知道那里发生了什么。

cond 已经内置了隐含的 begin ,所以最好说:

 (cond [<test>
        <body-1>
        <...>
        <body-n>] ...)

而不是:

(cond [<test>
       (begin
         <body-1>
         <...>
         <body-n>)] ...)