【问题标题】:Partition help scheme分区帮助方案
【发布时间】:2013-02-22 12:18:16
【问题描述】:

我有以下代码,但是当我运行这个例子时:

(partition 12 '(4 9 18 6 19 10 18 11 5 5 7 2 4 19 1 9 10 18 12))

我明白了

((4 9 6 10 11 5 5 7 2 4 1 9 10 12) (18 19 18 19 18)) 

作为回报。

我想要它如下

((4 9 6 10 11 5 5 7 2 4 1 9 10 12) 18 19 18 19 18)

我应该怎么做才能改变这一点?谢谢支持

      (require (lib "trace.ss"))
        (define (partition pivot lon)
          (if (null? lon)
              '(()())
              (let ((split-of-rest (partition pivot (cdr lon))))
                (if (<= (car lon) pivot)
                    (list (cons (car lon) (car split-of-rest))
                          (cadr split-of-rest))
                    (list (car split-of-rest) (cons (car lon)
                                                    (car (cdr split-of-rest))))))))

【问题讨论】:

    标签: scheme


    【解决方案1】:

    我就是这样解决的:

    (define (partition pivot lon)
      (define (partition pivot lon less more)
        (if (null? lon)
          (cons less more)
          (if (<= (car lon) pivot)
            (partition pivot (cdr lon) (append less (list (car lon))) more)
            (partition pivot (cdr lon) less (append more (list (car lon)))))))
      (partition pivot lon '() '()))
    

    不知道这是不是您正在寻找的解决方案。

    【讨论】:

      【解决方案2】:

      在某些 Scheme 解释器(例如 Racket)中,有一个内置的 partition 过程。或者,它也包含在SRFI 1 中。如果可以使用它,它将简化您的代码:

      (define (my-partition val lst)
        (let-values (((low high) (partition (lambda (x) (<= x val)) lst)))
          (cons low high)))
      

      partition 返回两个值,第一个是满足谓词的元素的列表,第二个是不满足谓词的元素的列表。使用cons 将它们组合起来很容易,以获得所需格式的结果。

      或者,我们可以使用call-with-values,正如@leppie 所建议的那样:

      (define (my-partition val lst)
        (call-with-values
         (thunk (partition (lambda (x) (<= x val)) lst))
         cons))
      

      不管怎样,结果如预期:

      (my-partition 12 '(4 9 18 6 19 10 18 11 5 5 7 2 4 19 1 9 10 18 12))
      => '((4 9 6 10 11 5 5 7 2 4 1 9 10 12) 18 19 18 19 18)
      

      【讨论】:

      • 使用 call-with-values 可能更简洁,只需将 cons 作为消费者传递。
      • @leppie 我想这是一个品味问题,但我更喜欢我的版本,对我来说它更清晰。无论如何,我用你的建议更新了答案;)
      • 我赞成 :) 也许有人无法编译 SRFI1 或有一个像样的方案;p
      • @leppie 加油,这不会使答案不正确!如果有人需要从头开始的工作解决方案,他们可以使用任何其他答案。我的解决方案很实用
      • @Oscar 我不认为你的回答真的那个有帮助,因为它归结为“不要编写自己的分区过程,使用别人写的”。这不是很有教育意义。如果 Scheme 最终成为另一种“不要思考,只需了解您的库”的语言,那么我会非常失望。
      【解决方案3】:

      我发现递归方法很困难,这里有一个更简单的迭代方法:

      (define (partition pivot lst)
        (let loop ((a '()) (b '()) (lst lst))
          (cond
            ((null? lst)          (cons (reverse a) (reverse b)))
            ((<= (car lst) pivot) (loop (cons (car lst) a) b (cdr lst)))
            (else                 (loop a (cons (car lst) b) (cdr lst))))))
      
      (partition 12 '(4 9 18 6 19 10 18 11 5 5 7 2 4 19 1 9 10 18 12))
      => '((4 9 6 10 11 5 5 7 2 4 1 9 10 12) 18 19 18 19 18)
      

      【讨论】:

      • 这可能是一个迭代过程,但无论如何它是一个尾递归过程
      • 这是一个迭代过程,与 OP 的递归过程相反。两者都是语法上的递归过程。
      • 没错,但这不是您的回答中所说的。您应该改写第一句话以更好地解释它
      • 奥斯卡对不起,我没明白你的意思。我在回答中没有使用“程序”或“过程”这两个词,所以我看不出任何矛盾。
      • 准确地说,对于新手来说,如果您声明一个过程是“迭代的”,这会让人感到困惑,但乍一看,很容易在代码中发现递归 调用。这就是为什么你应该澄清过程是迭代的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多