Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.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
Scheme 从列表中删除元素_Scheme_Racket - Fatal编程技术网

Scheme 从列表中删除元素

Scheme 从列表中删除元素,scheme,racket,Scheme,Racket,有人告诉我这个代码有什么问题。我以为我掌握了一些解决朋友问题的技巧,但结果弄糊涂了。我正在尝试从列表中删除所有类似的元素。之前它只移除了我想移除的第一个元素,但现在它移除了汽车和我想移除的第一个元素。我正在寻找这样的输出:(delete 3(list 2 3 4 3 5 3)),returns(2 4 5) 这是因为这个条件: ((equal? n (car lst)) (cdr lst)) 此行的作用是检查n是否与列表中的第一个元素相同。如果是,则返回列表的其余部分。因为您的目标元素是列表的

有人告诉我这个代码有什么问题。我以为我掌握了一些解决朋友问题的技巧,但结果弄糊涂了。我正在尝试从列表中删除所有类似的元素。之前它只移除了我想移除的第一个元素,但现在它移除了汽车和我想移除的第一个元素。我正在寻找这样的输出:
(delete 3(list 2 3 4 3 5 3))
,returns(2 4 5)


这是因为这个条件:

((equal? n (car lst)) (cdr lst))
此行的作用是检查
n
是否与列表中的第一个元素相同。如果是,则返回列表的其余部分。因为您的目标元素是列表的第二个元素,所以它返回列表的其余部分,从第三个元素开始。列表中的第一个元素已完全删除。您没有跟踪到目前为止检查过的OK元素

从您的代码中,看起来您希望循环列表中的元素,如果找到目标值,请调用
remove
。如果您想以这种方式实现它,还需要跟踪您检查和验证的不是目标值的值。因此,您的函数需要接受三个参数:
n
,即您的目标
lst
要检查的剩余数字;和
clean
(或者你想叫它什么名字)来保存已经检查过的号码

这是您的算法的工作版本:

(define (delete n lst clean)
  (cond
    ((empty? lst) clean)
    ((equal? n (car lst)) (delete n (cdr lst) clean))
    (else
      (delete n (cdr lst) (append clean (list (car lst)))))))
您可以这样称呼它:
(删除3(列表2 3 4 3 5 3))

首先,它会检查您是否还有需要检查的数字。如果您没有,它将返回您的干净列表

然后检查第一个元素是否与目标元素匹配。如果是,则再次调用delete,有效地删除
lst
中的第一个元素(注意,它不会将其附加到干净的数字列表中)

如果第一个元素不是目标编号,则会到达else,它将
lst
的第一个值附加到
clean
的末尾,并再次调用delete

(请注意,此代码使用尾部递归,这是一种编写递归方法的方法,用于跟踪每次递归调用的中间值,而不是在最后进行计算的“常规”递归。下面Samrat的回答是一个常规递归解决方案。尾部递归的讨论。)

从您的帖子中,听起来您希望删除目标编号的所有实例。与其使用
remove
函数(只删除目标编号的第一个实例),不如考虑使用
remove*
函数(删除所有实例)。这将大大简化您的功能。因此,要从列表中删除3的所有实例,这就足够了:

(remove* '(3) (list 2 3 4 3 5 3))
如果要将其包装到函数中:

(define (delete n lst)
  (remove* (list n) lst))

一般来说,你应该仔细阅读,因为他们基本上都是你想要的。(它们对列表中的所有元素应用一个过程;如果您有一个更复杂的过程,也可以使用
过滤器映射来实现上述操作。)

这是由于以下条件:

((equal? n (car lst)) (cdr lst))
此行的作用是检查
n
是否与列表中的第一个元素相同。如果是,则返回列表的其余部分。因为您的目标元素是列表的第二个元素,所以它返回列表的其余部分,从第三个元素开始。列表中的第一个元素已完全删除。您没有跟踪到目前为止检查过的OK元素

从您的代码中,看起来您希望循环列表中的元素,如果找到目标值,请调用
remove
。如果您想以这种方式实现它,还需要跟踪您检查和验证的不是目标值的值。因此,您的函数需要接受三个参数:
n
,即您的目标
lst
要检查的剩余数字;和
clean
(或者你想叫它什么名字)来保存已经检查过的号码

这是您的算法的工作版本:

(define (delete n lst clean)
  (cond
    ((empty? lst) clean)
    ((equal? n (car lst)) (delete n (cdr lst) clean))
    (else
      (delete n (cdr lst) (append clean (list (car lst)))))))
您可以这样称呼它:
(删除3(列表2 3 4 3 5 3))

首先,它会检查您是否还有需要检查的数字。如果您没有,它将返回您的干净列表

然后检查第一个元素是否与目标元素匹配。如果是,则再次调用delete,有效地删除
lst
中的第一个元素(注意,它不会将其附加到干净的数字列表中)

如果第一个元素不是目标编号,则会到达else,它将
lst
的第一个值附加到
clean
的末尾,并再次调用delete

(请注意,此代码使用尾部递归,这是一种编写递归方法的方法,用于跟踪每次递归调用的中间值,而不是在最后进行计算的“常规”递归。下面Samrat的回答是一个常规递归解决方案。尾部递归的讨论。)

从您的帖子中,听起来您希望删除目标编号的所有实例。与其使用
remove
函数(只删除目标编号的第一个实例),不如考虑使用
remove*
函数(删除所有实例)。这将大大简化您的功能。因此,要从列表中删除3的所有实例,这就足够了:

(remove* '(3) (list 2 3 4 3 5 3))
如果要将其包装到函数中:

(define (delete n lst)
  (remove* (list n) lst))

一般来说,你应该仔细阅读,因为他们基本上都是你想要的。(它们对列表中的所有元素应用一个过程;如果您有一个更复杂的过程,也可以使用
过滤器映射来实现上述操作。)

以下是我的想法:

(define (delete n lst)
  (cond ((empty? lst) lst)
        ((= (car lst) n) (delete n (cdr lst)))
        (else (append (list (car lst)) (delete n (cdr lst))))))

以下是我的想法:

(define (delete n lst)
  (cond ((empty? lst) lst)
        ((= (car lst) n) (delete n (cdr lst)))
        (else (append (list (car lst)) (delete n (cdr lst))))))