首页 文章

如何在Scheme中使用Car和Cdr打破(11(12 13))

提问于
浏览
3

我需要从列表中返回那些奇怪的值,所以我试图使用car和cdr函数打破我的列表 . 我有一个递归函数调用,检查Car是否返回一个列表然后使用car和cdr进一步打破它,否则只是将第一个元素传递给函数调用检查Odd .

特殊情况(10 11(12 13))的问题是汽车返回10 cdr回报(11(12 13))

然后在第二次迭代中汽车返回(11(12 13))cdr返回(11(12 13))

那我怎么能用汽车和cdr进一步打破我的清单 . 我需要在最终答案中保留括号,并且只返回具有奇数整数值的列表 .

3 回答

  • 1

    对于需要在任意嵌套列表上工作的函数,我发现很容易首先编写平面列表版本(在我们的例子中为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))])))
    

    需要注意的是,此设计模式可用于帮助编写任何递归程序,并将其从仅在平面列表上工作转换为在任意深度列表上工作 .

  • 4

    对于具有任意嵌套级别的列表,这是一个通用解决方案:

    (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))))))
    

    请注意,需要考虑三种情况:

    • 如果列表为空

    • 如果列表的第一个元素不是列表

    • 如果列表的第一个元素是列表

    对于第二种情况,需要考虑另外两种情况:

    • 如果元素是奇数,那么我们将它添加到返回的列表中

    • 如果元素是偶数,我们跳过它并继续下一个元素

  • 0

    这是我的看法:

    (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)
    

相关问题