仅使用“The Little Planer”中的表格来展平列表

发布于 2024-12-03 05:27:12 字数 277 浏览 1 评论 0原文

我正在通过《The LIttle Schemer》来学习Scheme(作为一名老C程序员),作为练习,我尝试编写一个过程来仅使用《Little Schemer》中的表单来展平列表;即,definelambdacondcarcdr等,但不是附加。我认为这很容易,但我一直无法想出解决方案。我该怎么做?

I'm going through The LIttle Schemer to learn Scheme (as an old C programmer) and as an exercise I tried to write a procedure to flatten a list using only the forms in The Little Schemer; I.e., define, lambda, cond, car, cdr, and, or, etc., but not append. I thought it would be easy but I haven't been able to come up with a solution. How can I do this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

御弟哥哥 2024-12-10 05:27:12

我有一个仅使用“第一原理”操作且高效的版本(与基于 append 的解决方案不同,不需要多次遍历任何列表)。 :-)

它通过定义两个简单的构建块(foldreverse),然后定义 flatten (及其帮助器 >reverse-flatten-into)在这些之上(并注意每个函数只有一两行长):

;; Similar to SRFI 1's fold
(define (fold1 kons knil lst)
  (if (null? lst)
      knil
      (fold1 kons (kons (car lst) knil) (cdr lst))))

;; Same as R5RS's reverse
(define (reverse lst)
  (fold1 cons '() lst))

;; Helper function
(define (reverse-flatten-into x lst)
  (if (pair? x)
      (fold1 reverse-flatten-into lst x)
      (cons x lst)))

(define (flatten . lst)
  (reverse (reverse-flatten-into lst '())))

唯一使用的外部函数是:conscar,<代码>cdr, null?pair?

该函数的关键见解是,fold 是一个非常强大的操作,并且应该成为任何计划者工具包的一部分。而且,如上面的代码所示,从第一原理构建起来非常简单!

I have a version that uses only "first-principles" operations and is efficient (does not require more than one pass through any of the lists, unlike append-based solutions). :-)

It does this by defining two simple building blocks (fold and reverse), and then defining flatten (and its helper, reverse-flatten-into) atop those (and notice how each function is just one or two lines long):

;; Similar to SRFI 1's fold
(define (fold1 kons knil lst)
  (if (null? lst)
      knil
      (fold1 kons (kons (car lst) knil) (cdr lst))))

;; Same as R5RS's reverse
(define (reverse lst)
  (fold1 cons '() lst))

;; Helper function
(define (reverse-flatten-into x lst)
  (if (pair? x)
      (fold1 reverse-flatten-into lst x)
      (cons x lst)))

(define (flatten . lst)
  (reverse (reverse-flatten-into lst '())))

The only external functions used are: cons, car, cdr, null?, and pair?.

The key insight from this function is that fold is a very powerful operation, and should be part of any Schemer's toolkit. And, as seen in the code above, it's so simple to build from first principles!

葬心 2024-12-10 05:27:12

我不熟悉 Little Schemer 原语,因此您可能需要对其进行调整以适应。

我不确定这是否是您想要的答案,但您可以使用原语编写 append

(define (append l1 l2)
  (cond
    ((null? l1) l2)
    (else (cons (car l1) (append (cdr l1) l2)))))

然后可以据此编写 flatten 函数。

不确定这是否超出规则:)

I'm not familiar with the Little Schemer primitives, so you may need to flavor this to suit.

I'm not sure if this is the answer you want, but you can write append using primitives:

(define (append l1 l2)
  (cond
    ((null? l1) l2)
    (else (cons (car l1) (append (cdr l1) l2)))))

The flatten function could then be written in terms of this.

Not sure if this is outside the rules or not :)

自演自醉 2024-12-10 05:27:12

这是一个尝试。它可以避免使用 cons 并避免追加,因为它只会削掉它可以到达的第一个非对,并将其压平它所构建的新尾部。有时它会重写列表,然后再次调用展平。绝对不是最有效的方法。

固定代码:

(define (flatten x)
  (cond 
    ((null? x) x)
    ((and (pair? x) 
          (not (pair? (car x))))
     (cond 
       ((null? (car x)) (flatten (cdr x)))
       (else (cons (car x) (flatten (cdr x))))))
    ((and (pair? x)
          (pair? (car x)))
     (flatten (cons (caar x) 
                    (cons (cdar x) (cdr x)))))
    (else (cons x '()))))

Here's an attempt. It gets away with using cons and avoiding append, because it only chips away the first non-pair it can get to and conses that to the flatten of a new tail it has built. Sometimes it rewrites the list then just calls flatten again. Def not the most efficient way.

Fixed code:

(define (flatten x)
  (cond 
    ((null? x) x)
    ((and (pair? x) 
          (not (pair? (car x))))
     (cond 
       ((null? (car x)) (flatten (cdr x)))
       (else (cons (car x) (flatten (cdr x))))))
    ((and (pair? x)
          (pair? (car x)))
     (flatten (cons (caar x) 
                    (cons (cdar x) (cdr x)))))
    (else (cons x '()))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文