Scheme函数删除第一个元素

时间:2010-05-02 11:43:58

标签: scheme elements

编写一个方案函数,删除给定项目的第一个顶级匹配项 从项目列表中。 例如给定列表(a b c)项目b,结果列表(a c)

请帮帮我

6 个答案:

答案 0 :(得分:3)

想想你想要完成什么。

您有一个东西列表,并且您正在尝试删除某个元素。

 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

答案 1 :(得分:1)

不确定你想要什么,但首先只用一个索引来启动它,这几乎是你必须“思考”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到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是第一个。

答案 2 :(得分:0)

有些功能车和cdr可以让你拿走列表的一部分。函数追加允许您将两个列表合并为一个。我认为它们可能会派上用场。还要查看cons函数,并确保您了解列表实际是什么以及它与对有什么关系。

例如,您可以按以下步骤操作。拿你的清单,切掉第一个元素并检查它是什么。如果是要删除的那个则丢弃它。如果它不是要删除的元素,则处理列表的其余部分,然后将该元素追加到开头。

答案 3 :(得分:0)

像这样的东西(如果是家庭作业):

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

答案 4 :(得分:0)

(define(remove-first-occurence list element)   (条件
    ((null?list)accum)     (其他          (cond((=(car list)element)(cons accum(cdr list)))          (否则(删除第一次出现(cdr list)元素(cons(car list)accum)))            )           )          )         )

(remove-first-occurence'(1 2 3)2'())

答案 5 :(得分:-1)

perl2scheme -s \
'use strict; sub remove_first { \
grep { $_ ne $_[0] || $first++ } @{ $_[1] }; } \
print join(",",remove_first("b", ("a","b","c"));'

实施perl计划的微不足道的任务留给读者练习。