[英]How to break (11 (12 13)) using Car and Cdr in Scheme
我需要从列表中返回那些奇怪的值,所以我试图使用car和cdr函数打破我的列表。 我有一个递归函数调用,检查Car是否返回一个列表然后使用car和cdr进一步打破它,否则只是将第一个元素传递给函数调用检查Odd。
特殊情况(10 11(12 13))的问题是汽车返回10 cdr回报(11(12 13))
然后在第二次迭代中汽车返回(11(12 13))cdr返回(11(12 13))
那我怎么能用汽车和cdr进一步打破我的清单。 我需要在最终答案中保留括号,并且只返回具有奇数整数值的列表。
对于需要在任意嵌套列表上工作的函数,我发现很容易首先编写平面列表版本(在我们的例子中为filter-odd),然后编辑它以生成嵌套版本(我将其称为filter-odd *)
首先是普通滤波器 - 奇数
(define filter-odd
(lambda (ls)
(cond
[(null? ls) '()]
[(odd? (car ls)) (cons (car ls) (filter-odd (cdr ls)))]
[else (filter-odd (cdr ls))])))
现在为过滤器奇数*(一个右侧将作为练习留下(虽然你似乎知道你的问题的答案))
(define filter-odd*
(lambda (ls)
(cond
[(null? ls) '()]
[(list? (car ls)) #| Do something with both car and cdr of ls |# ]
[(odd? (car ls)) (cons (car ls) (filter-odd* (cdr ls)))]
[else (filter-odd* (cdr ls))])))
需要注意的是,此设计模式可用于帮助编写任何递归程序,并将其从仅在平面列表上工作转换为在任意深度列表上工作。
对于具有任意嵌套级别的列表,这是一个通用解决方案:
(define (odds-list lst)
(cond ((null? lst) '()) ; the list is empty
((not (list? (car lst))) ; first element is not a list
(if (odd? (car lst)) ; element is odd
(cons (car lst) (odds-list (cdr lst))) ; build the returned list
(odds-list (cdr lst)))) ; element is even
(else (cons (odds-list (car lst)) ; first element is a list
(odds-list (cdr lst))))))
请注意,需要考虑三种情况:
对于第二种情况,需要考虑另外两种情况:
这是我的看法:
(define filter*
(lambda (e f)
(cond ((pair? e)
(append (filter* (car e) f)
(filter* (cdr e) f)))
((null? e) '())
((f e) (list e))
(else '()))))
然后你可以这样做:
> (filter* '(1 (2 . 3) ((4 . 5))) even?)
(2 4)
> (filter* '(1 (2 . 3) ((4 . 5))) odd?)
(1 3 5)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.