【问题标题】:(Racket) Return a sublist of a list that satisfy a condition(Racket) 返回满足条件的列表的子列表
【发布时间】:2021-01-22 22:02:03
【问题描述】:

我在编写返回满足条件的对子列表的函数时遇到问题。

当前代码:

(define lst1 '((a . 8)(b . 3)(c . 1)(d . 9)(e . 4)))

(define (letter t)
  (caar t))

(define (numb p)
  (cdar p))

(define (satisfy? c? lst)
  (cond
    [(or (c? (letter lst)) (c? (numb lst))) #t]
    [else #f]))

(define (find-sublist c? lst)
  (cond
    [(satisfy? c? lst) (cons (car lst) (find-sublist c?(cdr lst)))]
    [else (find-sublist c? (cdr lst))]))

控制台输入:

(find-sublist (lambda(x) (> (numb x) 3)) lst1)

想要的输出:

'((a . 8)(d . 9)(e . 4))

我当前的输入包括违反合同或对的合同

car: contract violation   
     expected: pair?   
     given: '()

cdar: contract violation
      expected: (cons/c pair? any/c)
      given: 'a

【问题讨论】:

    标签: functional-programming scheme racket


    【解决方案1】:

    您的代码有几个问题:

    • letter 和 numb 过程在列表元素上运行,而不是在列表上,所以它们应该只是car和cdr。
    • 您忘记了基本情况,当列表为空时会发生什么?
    • 不要将() 放在lst 周围,这不是程序。
    • 更重要的是:您的satisfy? 程序尝试对号码上的字母or 进行操作,但在lambda 中您已经提取了该号码。解决方案就是摆脱这个过程(或者,不要提取lambda 中的数字,但是您必须在应用条件之前测试lambda 的参数是否为数字。 )

    这应该可以解决问题:

    (define (letter t)
      (car t))
    
    (define (numb p)
      (cdr p))
    
    (define (find-sublist c? lst)
      (cond
        [(null? lst) '()]
        [(c? (car lst)) (cons (car lst) (find-sublist c? (cdr lst)))]
        [else (find-sublist c? (cdr lst))]))
    

    它按预期工作:

    (define lst1 '((a . 8) (b . 3) (c . 1) (d . 9) (e . 4)))
    (find-sublist (lambda (x) (> (numb x) 3)) lst1)
    => '((a . 8) (d . 9) (e . 4))
    

    仅供参考,您重新实现了内置的 filter 过程。您应该尽可能使用现有程序;)

    (filter (lambda (x) (> (numb x) 3)) lst1)
    => '((a . 8) (d . 9) (e . 4))
    

    【讨论】:

    • (编号项目符号) 1. 是的 2. 如果我已经在另一个程序中检查了列表不为空,我还需要包括这一行吗? 3. 是的,错字。编辑 4. 啊,这让事情变得更清楚了!谢谢!
    • 关于 2:你在别处检查它并不重要,我们在这里建立一个新列表,在某些时候递归会将lst 变成一个空列表。所有递归过程都需要一个基本案例!对于通过使用输入列表来构建新列表,基本情况将始终是检查空列表并返回一个空列表。
    • 您的观点(1)不完整:在问题中,字母和数字函数对列表进行操作,而不仅仅是列表元素;它们的定义与过程find-list 匹配,该过程将列表的其余部分传递给它们,而不仅仅是第一个元素。毫无疑问,最好像您一样做,并将它们都修复为仅对单个元素进行操作;但是这两个程序必须就它们之间流动的数据达成一致。
    • @OscarLopez 是的,这是有道理的!我接受了你的回答。我也赞成您的回答,但我的声誉不到 15 个,因此不会公开出现。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-08
    • 2021-06-08
    • 2018-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多