【问题标题】:Implementation of LIFO list in SchemeScheme中LIFO列表的实现
【发布时间】:2015-05-28 11:24:21
【问题描述】:

我在 Scheme 中实现 LIFO 列表时遇到了一些问题。如果我只想将一个元素压入堆栈,我的代码工作得很好,但我希望能够压入多个元素。这是我的代码:

(define (make-stack)
(let ((stack '()))
    (lambda (msg . args)
      (cond ((eq? msg 'pop!)
             (set! stack (cdr stack)))
            ((eq? msg 'push!) 
             (if (= 1 (length args))
                 (set! stack (cons args stack))
                 (push stack args)))
            ((eq? msg 'stack) stack)
            (else "Not valid message!")))))
(define (push stack args)
  (if (null? args)
      stack
      (set! stack (cons (car args) stack)))
  (push stack (cdr args)))

这只是我最后一次尝试,我尝试了很多方法,数不胜数。我只是不明白如何从“args”中取出元素并将它们一一添加到堆栈中。 “推送”过程根本不起作用,我只是在最后一行得到一个错误(也许我的递归是错误的)。正如我所说,这是我最后一次尝试,我无法理解它。

编辑:

我现在已经尝试实现 push!,pop!并将堆栈作为独立过程,将堆栈对象作为参数。流行音乐!并推!很容易,但在推动!我要添加的元素已经嵌套在推送列表中!因此,当我将它发送到 make-stack 过程时,它会以嵌套列表的形式出现。我试图做一个递归过程来解决这个问题:

(define (push! lifo . args)
   (if (null? args)
        lifo
        (lifo 'push! (car args))
   (push! lifo (cdr args))

这只是进入一个循环,我不明白为什么......(递归对我来说是个大问题)

【问题讨论】:

    标签: list stack scheme r5rs lifo


    【解决方案1】:

    也许:

    (define (make-stack)
      (let ((stack '()))
        (lambda (msg . args)
          (cond 
            [(eq? msg 'pop!)  (set! stack (cdr stack))]
            [(eq? msg 'push!) (set! stack (append (reverse args) stack))]
            [(eq? msg 'stack) stack]
            [else "Not valid message!"]))))
    
    (define s (make-stack))
    (s 'push! 'a)
    (s 'push! 'b 'c 'd)
    (s 'stack)
    (s 'pop!)
    (s 'stack)
    

    输出:

    '(d c b a)
    '(c b a)
    

    【讨论】:

    • 我会做两处改变:1. 使用 SRFI 1,你可以使用append-reverse,它更直接(它跳过两个反转,或者一个反转和一个右折叠,具体取决于append 是如何实现的); 2. 我会使用case 而不是cond(以及它的服务员eq? 检查)。
    • 中肯的建议。我用 cond 来模仿原始程序,但是 case 看起来更漂亮。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-13
    • 1970-01-01
    • 2020-04-22
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    相关资源
    最近更新 更多