Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion 查找并删除列表[球拍]中指定元素的最后一次出现_Recursion_Scheme_Racket - Fatal编程技术网

Recursion 查找并删除列表[球拍]中指定元素的最后一次出现

Recursion 查找并删除列表[球拍]中指定元素的最后一次出现,recursion,scheme,racket,Recursion,Scheme,Racket,我已经开始编写一个函数,用于查找列表中最后出现的元素。我的想法是使用search计算指定符号的出现次数并返回它。然后我将计数传递到removeLast中,这将删除元素。然后,我将在removeLast中减少计数,以方便基本情况。从我所看到的使用set通常是不好的做法。是否有更好/更优雅的方式“记住”符号的最后一次出现 (define (lastLess lis symbol) (define count 0) (set! count (search symbol lis count))

我已经开始编写一个函数,用于查找列表中最后出现的元素。我的想法是使用
search
计算指定符号的出现次数并返回它。然后我将计数传递到
removeLast
中,这将删除元素。然后,我将在
removeLast
中减少计数,以方便基本情况。从我所看到的使用
set通常是不好的做法。是否有更好/更优雅的方式“记住”符号的最后一次出现

(define (lastLess lis symbol)
  (define count 0)
   (set! count (search symbol lis count))
  (removeLast symbol lis count)
)

(define (search symbol lis count )
  ( cond ((null? lis) count)
     ( (eq? symbol (car lis)) (+ count (add1 (search symbol (cdr lis) count ))) )
     ( (pair? (car lis))(+ count(+ 0 (search symbol (car lis) count ))))
     ( else (+ count(+ 0 (search symbol (cdr lis) count))))
     )
)

(define (removeLast symbol lis count)
  (cond ((null? lis) '())
    ((eq? count 0) (cdr lis))
    ((eq? symbol (car lis)) ((set! count (sub1 count)) 
                             (cons (car lis)(removeLast symbol (cdr lis) count))
                            )
                            )
    ((pair? (car lis)) (removeLast symbol (car lis) count))
    (else (cons (car lis) (removeLast symbol (cdr lis) count )))
    )
)
((set!count(sub1 count))(cons(car-lis)(removeLast-symbol(cdr-lis)count)))运行代码会抛出错误:

应用:不是一个程序; 应为可应用于参数的过程 鉴于:# 论据。。。: "(e)


编辑:这是一个类的赋值,所以多余的
reverse
s是不可接受的,我必须说明嵌套列表。

您应该使用内置过程来完成此操作。特别要注意的是,
remove
删除了与
symbol
相等的
lis
的第一个元素,因此删除最后一个元素很简单,只需颠倒列表即可:

(define (lastLess lis symbol)
  (reverse (remove symbol (reverse lis))))

(lastLess '(1 2 3 4 5 1) 1)
=> '(1 2 3 4 5)
上述解决方案根本不需要使用
set——尽管可以通过改变列表来解决此问题,但在Scheme中还是首选功能解决方案


当然,可以编写一个更有效的解决方案,一个只遍历列表一次的解决方案,但是问问自己:您真的需要这种解决方案增加的复杂性吗?高绩效如此重要吗?如果答案是否定的,那么坚持使用更简单、更清晰的解决方案。

您遇到的错误来自
cond
子句。在(set!count…)周围有额外的括号

你的问题是你对布景的痴迷! 这:

本来可以做到的

(define (lastLess lis symbol)
  (removeLast symbol lis (search symbol lis 0)))
或者我想让你做作业,如果把结果用在多个地方,这很好

(define (lastLess lis symbol)
  (let ((count (search symbol lis 0)))
    (if (< 0 count) ; noe or more occurences
        (removeLast symbol lis count)
        lis)))
注意如何处理对。现在,当count为零时,但当符号匹配且count为1时,removeLast不应跳过它得到的任何值


祝你好运

这仍然使用set,但我认为这是一个更优雅的解决方案,因为set是在匿名函数的闭包中使用的,您可以将其作为参数foldr传递。if找到第一个匹配项后(请记住从尾部开始工作,它会将自身停用以作为cons。由于foldr从列表的尾部开始工作,因此不需要额外的遍历。make remover是一个功能性过程(一个输入将始终映射到同一个输出)然而,输出是非函数的,但这并不是什么大问题,因为您只使用了一次,然后就把它扔掉了


这不会遍历树(在嵌套列表上工作),但在将过程应用于子列表之前,将foldr修改为将在子列表上进行foldr的foldr树应该不会太困难。

现在这也会考虑嵌套列表吗?这是课堂作业,我的教授说“重复的反转是不可接受的。”我非常感谢您的输入。这个答案是在编辑之前发布的,不-它没有考虑嵌套列表,实际上它执行了几个(冗余?)反转。编辑之后,这个问题是一个完全不同(更难)的问题。抱歉,我现在找不到答案,这里已经过了午夜:)
(define (lastLess lis symbol)
  (let ((count (search symbol lis 0)))
    (if (< 0 count) ; noe or more occurences
        (removeLast symbol lis count)
        lis)))
(define (search symbol lis count)
  (cond ((null? lis) count)
     ((eq? symbol (car lis)) (search symbol (cdr lis) (add1 count)))
     ((pair? (car lis)) (search symbol (cdr lis)
                                (search symbol (car lis) count)))
     (else (search symbol (cdr lis) count))))
(define (remove-last x L)
 (let ((proc (make-remover x)))
  (foldr proc '() L)))


(define (make-remover removee)
 (let ((active? #t))
  (lambda (x y)
   (cond ((not active?) (cons x y))
         ((eq? x removee) (begin (set! active? #f) y))
         (else (cons x y))))))