Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.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_Functional Programming_Ocaml - Fatal编程技术网

Recursion 使用前向递归删除列表元素

Recursion 使用前向递归删除列表元素,recursion,functional-programming,ocaml,Recursion,Functional Programming,Ocaml,我正在写一个程序,删除第一个适合谓词eg的元素 remove' (fun x -> x = 2) [1;3;2;4;2] => [1;3;4;2] 问题是:如何用forward递归编写它?可能吗?对于尾部递归,这不是问题。我只是将下一个元素添加到acc中,如果它们不适合谓词 我在想 List.fold_right, 但是可能有不同的方法来实现这一点吗?没有所谓的“前向递归”。尾部递归定义了一种特殊的递归,它发生在尾部位置。当您想要引用一个不在尾部位置的递归时,可以称之为“非尾部递

我正在写一个程序,删除第一个适合谓词eg的元素

remove' (fun x -> x = 2) [1;3;2;4;2] => [1;3;4;2]
问题是:如何用forward递归编写它?可能吗?对于尾部递归,这不是问题。我只是将下一个元素添加到acc中,如果它们不适合谓词

我在想

List.fold_right,
但是可能有不同的方法来实现这一点吗?

没有所谓的“前向递归”。尾部递归定义了一种特殊的递归,它发生在尾部位置。当您想要引用一个不在尾部位置的递归时,可以称之为“非尾部递归”

在您指定的代码中,根本没有递归。因此,我建议您首先尝试编写
remove\u if
函数,并尝试确定它是尾函数还是非尾函数

更新 我通常尝试不为其他人解决家庭作业,但在这种情况下,我会给你一点启发,为你提供最常见的
remove\u if
函数定义:

 let rec remove matches = function
    | [] -> []
    | x :: xs when matches x -> remove matches xs
    | x :: xs -> x :: remove matches xs
| x :: xs when matches x -> remove matches xs
                            ^^^^^^^^^^^^^^^^^
                            last expression - 
                            tail recursion

| x :: xs -> x :: remove matches xs
                  ^^^^^^^^^^^^^^^^^
                  not the last - 
                  non tail recursive
此函数中出现两次递归:

 let rec remove matches = function
    | [] -> []
    | x :: xs when matches x -> remove matches xs
    | x :: xs -> x :: remove matches xs
| x :: xs when matches x -> remove matches xs
                            ^^^^^^^^^^^^^^^^^
                            last expression - 
                            tail recursion

| x :: xs -> x :: remove matches xs
                  ^^^^^^^^^^^^^^^^^
                  not the last - 
                  non tail recursive
因此,最后一种情况需要澄清:在将
x
添加到
remove matches xs
的结果之前,需要计算后一个表达式。这意味着计算机需要将
x
存储在某个地方,等待
删除匹配项xs
被评估


所以,有趣的是,你有一个非尾部递归版本。现在,尝试递归地实现它。享受
乐趣

ivg解决方案对我帮助很大,但我需要稍微升级一下。我的答案是:

 let remove' p xs =
   let rec remove_guard p xs g =
      match xs with 
        [] -> []
      | hd::tl -> if (p hd && g = 1) then remove_guard p tl 0 
                  else  hd::remove_guard p tl g
 in remove_guard p xs 1
也许不是最好的,但它只删除了一个元素


谢谢你们的帮助。我真的很感激。

我读过stackoverflow上的“向前递归”。对不起,如果我弄错了。关键是,我必须编写“非尾部递归”和“尾部递归”删除函数。正如我所说,“非尾部递归”算法对我来说是个问题。实际上,我认为您应该首先尝试编写
remove\u if
函数的任何实现。(通常的定义实际上是非尾部递归的,因此很难编写尾部递归)。而且,据我所知,你不能使用库函数来编写
remove\u if
,你需要使用recursionok,因为你对术语一无所知,我给你展示了一个简单的非尾部递归实现的例子。折叠就足够了,只要
让remove\u if pl=List.fold\u right(fun e A->if pe then A else e::A)l[]
。当然,这不是OP要求的唯一删除操作。(也可以使用
fold_right
,但这很难看。)使用累加器是实现尾部递归的一种特殊方法,其他方法也可以,例如继续传递。不错,但可以做得更好,而不是在第一次与保护标志匹配后继续递归(顺便说一句,这里有一个
bool
类型),你可以选择根本不递归,因为结果已经准备好了,你是有权利的。你是我的英雄D再次感谢!这不仅仅是关于家庭作业,而且我真的很喜欢函数式编程(我用Python编程,它的函数性很差,但仍然可以编程。)它帮助我发展我的技能。