简体   繁体   English

我如何仅使用 cons 和空列表创建列表? 球拍

[英]How can i create a list just using cons and empty list? Racket

Hi have been asked as to build the following lists,just by using cons and the empty list.I attempted to do the first one,i tried this first,for the first list.嗨,有人问我要构建以下列表,只需使用 cons 和空列表。我尝试做第一个,我首先尝试了这个,用于第一个列表。

(cons (cons 1 (cons 2 '())) (cons 3 (cons 2 '())))  this was the output '((1 2) 3 2)

i also tried this (cons (cons 1 '()) (cons (cons 2 '())) (cons 3 (cons 4 '())) '())我也试过这个(cons (cons 1 '()) (cons (cons 2 '())) (cons 3 (cons 4 '())) '())

but it kept returning augment errors,can someone explain how should i apply the empty lists and cons to obtain the required results但它不断返回增加错误,有人能解释一下我应该如何应用空列表和缺点来获得所需的结果吗

‘(1 (2 ( 3 2 ))) 
 '(1 2 (3 4 (5))) 
 '(((1 2 3))) 
 '((1 (2)) 3 4) 

A nice way to answer this question is not to: instead write a program which will answer it for you : you want a program which, given some object, will return a description of a program which will make it for you.回答这个问题的一个好方法不是:而是编写一个将为您回答的程序:您想要一个程序,给定一些 object,它将返回一个程序的描述,该程序将为您制作。 Here is one such:这是一个这样的:

(define (make-cons-tree-maker tree)
  ;; Note this assumes that the trees are trees.
  (cond
    [(null? tree)
     ;; If the tree is null then it is made by '().  This case is not needed
     ;; (why?)
     '(quote ())]
    [(cons? tree)
     ;; If the tree is a cons we make it by the cons function
     `(cons ,(make-cons-tree-maker (car tree))
            ,(make-cons-tree-maker (cdr tree)))]
    [(symbol? tree)
     ;; Symbols need quoting.  This case is not strictly needed either
     `(quote ,tree)]
    [(or (number? tree)
         (string? tree))
     ;; Numbers and strings do not need quoting
     tree]
    [else
     ;; But assume anything else does (this is safe)
     `(quote ,tree)]))

And now现在

> (make-cons-tree-maker '(x y))
'(cons 'x (cons 'y '()))

In fact, as the comments in the function say, it can be made a lot simpler, if you are willing to accept that the instructions it returns are not minimal:事实上,正如 function 中的评论所说,它可以变得更简单,如果你愿意接受它返回的指令不是最少的:

(define (make-cons-tree-maker tree)
  ;; Note this assumes that the trees are trees.
  (if (cons? tree)
     ;; If the tree is a cons we make it by the cons function
     `(cons ,(make-cons-tree-maker (car tree))
            ,(make-cons-tree-maker (cdr tree)))
     ;; otherwise just quote it
     `(quote ,tree)))

This will return the same result for the above tree:这将为上面的树返回相同的结果:

> (make-cons-tree-maker '(x y))
'(cons 'x (cons 'y '()))

But its result has a lot of unneeded quote s for some other trees:但它的结果对其他一些树有很多不需要的quote

> (make-cons-tree-maker '(1 2 3 "foo" . 4))
'(cons '1 (cons '2 (cons '3 (cons '"foo" '4))))

And finally you can of course do this, which entertains you if this sort of thing entertains you:最后你当然可以这样做,如果这种事情让你开心,这会让你开心:

> (make-cons-tree-maker '(define (make-cons-tree-maker tree)
                           ;; Note this assumes that the trees are trees.
                           (if (cons? tree)
                               ;; If the tree is a cons we make it by the cons function
                               `(cons ,(make-cons-tree-maker (car tree))
                                      ,(make-cons-tree-maker (cdr tree)))
                               ;; otherwise just quote it
                               `(quote ,tree))))
'(cons
  'define
  (cons
   (cons 'make-cons-tree-maker (cons 'tree '()))
   (cons
    (cons
     'if
     (cons
      (cons 'cons? (cons 'tree '()))
      (cons
       (cons
        'quasiquote
        (cons
         (cons
          'cons
          (cons
           (cons
            'unquote
            (cons
             (cons
              'make-cons-tree-maker
              (cons (cons 'car (cons 'tree '())) '()))
             '()))
           (cons
            (cons
             'unquote
             (cons
              (cons
               'make-cons-tree-maker
               (cons (cons 'cdr (cons 'tree '())) '()))
              '()))
            '())))
         '()))
       (cons
        (cons
         'quasiquote
         (cons (cons 'quote (cons (cons 'unquote (cons 'tree '())) '())) '()))
        '()))))
    '())))

When you're learning about pairs and lists, it can be useful to draw a Cons-cell diagrams.当您学习对和列表时,绘制 Cons-cell 图会很有用。 There's a great Racket library Sdraw , which visualizes given list or pair- so I used it to show you structure of created lists:有一个很棒的 Racket 库Sdraw ,它可视化给定的列表或对 - 所以我用它来向您展示创建列表的结构:

#lang racket
(require sdraw)

; '(1 (2 (3 2)))
(sdraw (cons 1 (cons (cons 2 (cons (cons 3 (cons 2 '())) '())) '())))
; '(1 2 (3 4 (5)))
(sdraw (cons 1 (cons 2 (cons (cons 3 (cons 4 (cons (cons 5 '()) '()))) '()))))
; '(((1 2 3)))
(sdraw (cons (cons (cons 1 (cons 2 (cons 3 '()))) '()) '()))
; '((1 (2)) 3 4)
(sdraw (cons (cons 1 (cons (cons 2 '()) '())) (cons 3 (cons 4 '()))))

There are two things to understand:有两点需要理解:

  • A cons cell is, informally, a kind of container.非正式地,cons cell 是一种容器。 It contains exactly two things, of any type, respectively its car and its cdr .它恰好包含任何类型的两个东西,分别是它的car和它的cdr
  • A list is a specific sequence of nested cons cells.列表是嵌套 cons 单元格的特定序列。 More precisely, a list is a chain of cons, in which the car of each cons represents an element of the list, and the cdr is either the next link of the chain, or '() .更准确地说,列表是 cons 链,其中每个 cons 的car代表列表的一个元素,而cdr是链的下一个链接,或者'()

A different formulation: a list is either '() , or a cons cell whose cdr is a list.一个不同的公式:一个列表要么是'() ,要么是一个cdr是一个列表的 cons 单元格。

Now, for your problem:现在,针对您的问题:

First example: '(1 (2 (3 2)))第一个例子: '(1 (2 (3 2)))

  • The first element of this list is 1 .此列表的第一个元素是1 According to what precedes, this means that 1 is the car of the first cons cell which makes up the list.根据前面的内容,这意味着1是构成列表的第一个 cons 单元格的car Hence, the expression will be of the form (cons 1 <something>) .因此,表达式的形式为(cons 1 <something>)
  • The next element of the list is itself a list, namely (2 (3 2)) .列表的下一个元素本身就是一个列表,即(2 (3 2)) This is also the last element of the list.这也是列表的最后一个元素。 This means that <something> is of the form (cons '(2 (3 2)) '()) .这意味着<something>的形式为(cons '(2 (3 2)) '()) Indeed, we have seen that a list must end with a cons cell of the form (cons element '()) ;实际上,我们已经看到列表必须以形式为(cons element '())的 cons 单元结尾; in that case, element is somewhat complicated, but you have to stick to the rules !在那种情况下, element有点复杂,但你必须遵守规则! This means that the full expression will be of the form (cons 1 (cons '(2 (3 2)) '()))这意味着完整的表达式将是(cons 1 (cons '(2 (3 2)) '()))

We need to "develop" the ugly '(2 (3 2)) form that we still have in the middle of the previous expression.我们需要“开发”我们在前面的表达式中间仍然存在的丑陋'(2 (3 2))形式。 We just follow the same rules: this is a list, the first element of which is 2 .我们只是遵循相同的规则:这是一个列表,第一个元素是2 It can therefore be written as (cons 2 <rest>) .因此它可以写成(cons 2 <rest>)

  • Its next element is itself a list, namely '(3 2) .它的下一个元素本身就是一个列表,即'(3 2) It also happens to be the last element of the list, so <rest> == (cons '(3 2) '()) .它也恰好是列表的最后一个元素,所以<rest> == (cons '(3 2) '())
  • Finally, and still following the same rules, '(3 2) == (cons 3 (cons 2 '())) .最后,仍然遵循相同的规则, '(3 2) == (cons 3 (cons 2 '()))

Putting everything together, we get that把所有东西放在一起,我们得到了

'(1 (2 (3 2))) == (cons 1 (cons (cons 2 (cons (cons 3 (cons 2 '())) '())) '()))

The last expression is confusing and pretty much unreadable, but you can get it by doing things slowly.最后一个表达式令人困惑且几乎不可读,但是您可以通过慢慢地做事来获得它。 The important thing is that重要的是

(a b c d ... z) == (cons a (cons b (cons c ... (cons z '()))))

regardless of how complex a, b... z actually are.不管a, b... z实际上有多复杂。 You can the just apply this "formula" (which is really just the definition of a list as a chain of cons cells), and continue to apply it if your sub-expressions are still lists rather than atoms.您可以只应用这个“公式”(实际上只是将列表定义为一系列 cons 单元格),如果您的子表达式仍然是列表而不是原子,则继续应用它。

Another interesting example: '(((1 2 3)))另一个有趣的例子:'(((1 2 3)))

This is a list of exactly one element, '((1 2 3)) .这是一个只有一个元素的列表, '((1 2 3)) It is therefore written as (cons <this element> '()) where <this-element> is still somewhat complicated.因此它被写为(cons <this element> '())其中<this-element>仍然有些复杂。

In particular, <this-element> is itself a list, It is of length 1, and has exactly one element, '(1 2 3) .特别是, <this-element>本身就是一个列表,它的长度为 1,并且只有一个元素'(1 2 3) It can therefore be written as (cons '(1 2 3) '())因此它可以写成(cons '(1 2 3) '())

Now, '(1 2 3) , by what precedes, is simply (cons 1 (cons 2 (cons 3 '()))) .现在, '(1 2 3) ,根据前面的内容,只是(cons 1 (cons 2 (cons 3 '())))

So '((1 2 3)) is just (cons (cons 1 (cons 2 (cons 3 '()))) '())所以'((1 2 3))只是(cons (cons 1 (cons 2 (cons 3 '()))) '())

... and finally ... 最后

'(((1 2 3))) == (cons (cons (cons 1 (cons 2 (cons 3 '()))) '()) '())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM