访问Scheme中列表中的元素

时间:2017-03-17 18:55:31

标签: scheme racket

我必须在方案中编写一个函数来访问元素' a'在以下列表中。 '(1(2 a 4 5))

我写了

(car (cdr (cdr '(1 (2 a 4 5)))))

但我收到错误

"car: contract violation
  expected: pair?
  given: '()"

如何解决此问题?

3 个答案:

答案 0 :(得分:0)

让我们先来看(2 a 4 5)。这是四个元素的列表:2,a,4和5。 可以使用函数cons

来构造这样的列表值
(cons 2 (cons 'a (cons 4 (cons 5 '()))))

其中'()是空列表。

可以像这样创建列表(1 X)

(cons 1 (cons X '()))

将第二个表达式与我们看到的第一个表达式

结合起来
(cons 1 (cons (cons 2 (cons 'a (cons 4 (cons 5 '())))) '()))

将构建列表(1 (2 a 4 5))

现在我们已经准备好了解会发生什么:

> (cdr (cons 1 (cons (cons 2 (cons 'a (cons 4 (cons 5 '()))))  ; the car
       '())))                                                  ; the cdr
(cons (cons 2 (cons 'a (cons 4 (cons 5 '())))) '())            ; 

> (cdr (cdr (cons 1 (cons (cons 2 (cons 'a (cons 4 (cons 5 '())))) '())))
= (cdr   (cons (cons 2 (cons 'a (cons 4 (cons 5 '()))))  ; the car
               '())                                      ; the cdr
= '()

> (car (cdr (cdr (cons 1 (cons (cons 2 (cons 'a (cons 4 (cons 5 '()))))
                       '()))))
= (car '())
= ERROR

在repl中尝试这个,然后看看你是否可以弄清楚如何继续:

(car (cdr  the-list-expression ))

答案 1 :(得分:0)

点符号中的

(1 (2 a 4 5)是:(1 . ((2 . (a . (4 . (5 . ())))) . ()))。对于每对(a . d),您使用c a r获取第一个,使用c d r获得第二个。如果您查看点符号,则需要将d传递给((2 . (a . (4 . (5 . ())))) . ()),然后a传递(2 . (a . (4 . (5 . ())))),然后d传递(a . (4 . (5 . ()))) }然后a获取a。您从头到尾订购它们(car (cdr (car (cdr '(1 (2 a 4 5)))))或者如果您再次查看这些字母并在开头添加c,最后r添加(cadadr '(1 (2 a 4 5)))

非常重要的是要知道(1 2 3 4)(1 . (2 . (3 . (4 . ())))),如果你想要第3个元素,它就是carcddr的{​​{1}}。在查看点符号时,从右到左阅读caddra。要成为d的母语人士,您需要做很多这些。点符号og cxr怎么样?您如何访问((1) (2))

当然,这对2可以使用(1 . 2)制作。

答案 2 :(得分:0)

从@ soegaard的回应开始...... 造成问题的原因是列表中包含一个列表。

(car (cdr '(1 (2 a 4 5))))开始,即'(2 a 4 5),您现在需要从该列表中提取第二个项目,您可以使用单个cadr程序执行,也可以将它们嵌套,生成{{1 }}

正如soegaard解释的那样,有一个"隐形"那里的空列表,解释了为什么需要(car (cdr (car (cdr '(1 (2 a 4 5))))))来获取列表。

请记住,(car (cdr '(1 (2 a 4 5))))是一个列表,因此您需要将其视为列表。获取cdr,然后从中拉出车。

正如@Sylwester所说,你可以将这些字母组合起来形成复合名称。 Racket最多支持四层,因此您可以创建所需的层(几乎没有)并使用'(2 a 4 5)获得相同的结果。

记住"隐形"空列表。这似乎是绊倒你的原因。