【问题标题】:How to break (11 (12 13)) using Car and Cdr in Scheme如何在 Scheme 中使用 Car 和 Cdr 破解 (11 (12 13))
【发布时间】:2012-04-12 13:06:13
【问题描述】:

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

特例 (10 11 (12 13)) 的问题在于 汽车返回 10 cdr 返回 (11 (12 13))

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

所以我怎样才能使用 car 和 cdr 进一步打破我的清单。我需要在最终答案中保留括号,并且只返回具有奇数整数值的列表。

【问题讨论】:

  • 我很困惑,(11 (12 13))car11。看起来您的程序中存在某种逻辑错误,因为在较高级别上,您描述的方法听起来像是可行的,只要您在遇到诸如 ((12 13)) 之类的列表时小心递归。

标签: list functional-programming scheme


【解决方案1】:

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

普通过滤器优先

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

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

【讨论】:

    【解决方案2】:

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

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

    注意需要考虑三种情况:

    1. 如果列表为空
    2. 如果列表的第一个元素不是列表
    3. 如果列表的第一个元素是列表

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

    1. 如果元素是奇数,则将其添加到返回的列表中
    2. 如果元素是偶数,我们跳过它并继续下一个元素

    【讨论】:

    • 非常感谢!它解决了我的问题。很高兴得到帮助:)!
    【解决方案3】:

    这是我的看法:

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

    【讨论】:

      猜你喜欢
      • 2020-03-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-23
      • 1970-01-01
      相关资源
      最近更新 更多