编写一个方案函数,从项目列表中删除给定项目的第一个顶级出现。例如给定列表(abc)项目b,结果列表(ac)
请帮帮我
想想你想要完成什么。
您有一个东西列表,并且您正在尝试删除某个元素。
example: trying to remove b
(a a a a b a a b a ...)
anything before first b should be kept and anything after it also..
so we have to spit out from our function:
a a a a + a a b a ...
如果我们将其简化为递归操作:
at any point looking through the list you can:
1. inspect element at front of the list and give it out to the result
and recursively inspect the rest of the list
2. stop if you found your element and
give out the rest of the list as you've accomplished your task
不知道你想要什么,但首先简单地从一个索引开始,这几乎就是你必须用Scheme“思考”的方式,首先从“如果它是第一个元素怎么办?”开始,那么答案当然是它应该是列表的其余部分。然后'好吧,如果它不是第一个怎么办',那么答案是'它应该将第一个作为应用于其余部分的相同程序的结果。',这就是 Scheme 需要的所有信息,很多情况下真的。
(define (slice-out lst k)
(if (<= k 0) (cdr lst) ; if we want to remove the first (0) element, surely the result is simply the tail of the list?
(cons (car lst) ; if it's higher than 0, we just cons the first element...
(slice-out (cdr lst) (- k 1))))) ; to the result of the same method applied to the tail but with one lower k.
> (slice-out '(a b c d e) 2)
===>(a b d e)
如果列表对于索引来说太短,则此函数返回错误。
但是,如果您想通过与另一个对象的某些相等性来切出,这个例子就足够了,我们现在不再将它切出我们达到 0,但如果它与搜索示例相同:
(define (slice-out-by-equality lst search)
(if (equal? (car lst) search) (cdr lst)
(cons (car lst)
(slice-out-by-equality (cdr lst) search))))
> (slice-out-by-equality '(a b c d e) 'c)
===> (a b d e)
使用相同的原理,但是如果未找到该项目,则返回错误。
关键是该方案有很多平等比较的风格,所以,我们真正想要的是:
(define (make-slice-out comparison)
(lambda (lst search)
(let loop ((lst lst))
(cond
((null? lst) '())
((comparison (car lst) search) (cdr lst))
(else (cons (car lst) (loop (cdr lst))))))))
这个例子展示了 Scheme 的全部内容,不确定你是否知道它,但我们在这里使用了一个闭包,这个函数实际上将任何二进制比较函数作为参数,然后评估你想要的函数,它也被清理了,如果没有找到它就不再出错,它返回它只是返回旧列表,因为如果它到达列表的末尾,没有任何内容被删除,它只是再次将它转换为 () 。
> ((make-slice-out =) '(1 2 3 6 3) 6)
===> (1 2 3 3); we just made an anonymous function here.
但是记住我们最初的函数,我们现在可以像这样简单地定义它,当提供谓词“等于?”时 我们的新函数实际上评估了我们的旧函数(具有现在已清理的重要资产):
(define slice-out-by-equality (make-slice-out equal?))
而且,还有更多的二进制比较,这个更奇特的例子怎么样:
(define slice-out-less-than (make-slice-out <))
我们以这种方式创建了一个函数,该函数将严格小于搜索词的第一个元素切掉,因此这是有效的:
> (slice-out-less-than '(573 284 238 174 92 47) 100)
====> (573 284 238 174 47)
尽管 47 也小于 100,但 92 是其中的第一个。
像这样的东西(如果是家庭作业):
(define (remove-first-occurence some-list find-symbol accum)
(cond
[(empty? some-list) accum]
[else (cond
[(= (first some-list) find-symbol) (cons accum (rest some-list))]
[else (remove-first-occurence (rest some-list) find-symbol (cons (first some-list) accum))]
)]))
(remove-first-occurence '(1 2 3 4 3) 3 empty)
(define (remove-first-occurence list element accum) (cond
((null?list) accum) (else (cond((= (car list) element) (cons accum (cdr list)))) (else(remove-first -occurence (cdr list) element(cons (car list) accum))) ) ) )
(删除第一次出现'(1 2 3)2'())
有那些功能 car 和 cdr 允许您参加列表的一部分。函数 append 允许您将两个列表合并为一个。我认为它们可能会派上用场。还要检查 cons 函数并确保您了解列表实际上是什么以及它与对有什么关系。
例如,您可以按以下方式进行。拿出你的清单,删掉第一个元素并检查它是什么。如果是要删除的,请丢弃它。如果不是要删除的元素,则处理列表的其余部分,然后将该元素附加到开头。
perl2scheme -s \ '使用严格; 子 remove_first { \ grep { $_ ne $_[0] || $first++ } @{ $_[1] }; } \ print join(",",remove_first("b", ("a","b","c"));'
实现 perl2scheme 的琐碎剩余任务留给读者作为练习。