我必须在方案中编写一个函数来访问元素' a'在以下列表中。 '(1(2 a 4 5))
我写了
(car (cdr (cdr '(1 (2 a 4 5)))))
但我收到错误
"car: contract violation
expected: pair?
given: '()"
如何解决此问题?
答案 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个元素,它就是car
或cddr
的{{1}}。在查看点符号时,从右到左阅读caddr
和a
。要成为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)
获得相同的结果。
记住"隐形"空列表。这似乎是绊倒你的原因。