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

List 如何在方案中使用Car和Cdr打破(11(12 13)),list,functional-programming,scheme,List,Functional Programming,Scheme,我只需要从列表中返回那些奇数值,所以我尝试使用car和cdr函数来打破我的列表。我有一个递归函数调用,它检查Car是否返回一个列表,然后使用Car和cdr进一步打破它,否则只需将第一个元素传递给函数调用检查(如果是奇数) 特例(10 11(12 13))的问题是 汽车返回10 cdr报告(11(12 13)) 然后在第二次迭代中 退车(11(12)(13)) cdr报告(11(12 13)) 那么,我如何使用car和cdr进一步打破我的列表呢。我需要保留最终答案中的括号,并且只返回具有奇数整型值

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

特例(10 11(12 13))的问题是 汽车返回10 cdr报告(11(12 13))

然后在第二次迭代中 退车(11(12)(13)) cdr报告(11(12 13))


那么,我如何使用car和cdr进一步打破我的列表呢。我需要保留最终答案中的括号,并且只返回具有奇数整型值的列表。

对于需要处理任意嵌套列表的函数,我发现很容易首先编写平面列表版本(在我们的例子中为奇数过滤器),然后编辑它以生成嵌套版本(我将其称为奇数过滤器*)

第一个是正常的奇数滤波器

(define filter-odd
   (lambda (ls)
      (cond
        [(null? ls) '()]
        [(odd? (car ls)) (cons (car ls) (filter-odd (cdr ls)))]
        [else (filter-odd (cdr ls))])))
现在是filter-odd*(一个右边将作为练习放在左边(尽管看起来你似乎从你的问题中知道答案))


请注意,此设计模式可用于帮助编写任何递归程序,并将其从仅处理平面列表转换为处理任意深度列表。

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

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

    我很困惑,
    (11(12 13))
    车是
    11
    。看起来您的程序中出现了某种逻辑错误,因为在较高的层次上,您所描述的方法听起来是可行的,只要您在遇到列表时小心递归,例如使用
    ((12 13))
    。非常感谢!它解决了我的问题。很高兴得到帮助:)!
    > (filter* '(1 (2 . 3) ((4 . 5))) even?)
    (2 4)
    > (filter* '(1 (2 . 3) ((4 . 5))) odd?)
    (1 3 5)