使用前向递归删除列表元素
Removing element of list with forward recursion
我正在编写一个程序,它删除适合谓词的第一个元素,例如。
remove' (fun x -> x = 2) [1;3;2;4;2] => [1;3;4;2]
问题是:正向递归怎么写?可能吗?使用尾递归,这不是问题。如果下一个元素不适合谓词,我只是将它们添加到 acc。
我在想
List.fold_right,
但也许有不同的方法来做到这一点?
没有"forward recursion"这样的东西。尾递归定义了一种特殊的递归,它发生在尾部位置。当你想引用一个不在尾部位置的递归时,你称它为"non tail recursive"
在您指定的代码中根本没有递归。所以,我建议你首先尝试编写 remove_if
函数并尝试弄清楚它是尾部还是非尾部。
更新
我通常尽量不为别人解决作业,但在这种情况下,我会通过为您提供 remove_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
因此,最后一个案例需要澄清一下:在 x
可以添加到 remove matches xs
的结果之前,需要评估后一个表达式。这意味着计算机需要将 x
存储在某处,以等到 remove matches xs
被计算。
所以,没有有趣的部分,你有一个非尾递归版本。现在,尝试递归地实现它。有fun
!
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
也许不是最好的,但它只删除了一个元素。
感谢大家的帮助。非常感谢。
我正在编写一个程序,它删除适合谓词的第一个元素,例如。
remove' (fun x -> x = 2) [1;3;2;4;2] => [1;3;4;2]
问题是:正向递归怎么写?可能吗?使用尾递归,这不是问题。如果下一个元素不适合谓词,我只是将它们添加到 acc。
我在想
List.fold_right,
但也许有不同的方法来做到这一点?
没有"forward recursion"这样的东西。尾递归定义了一种特殊的递归,它发生在尾部位置。当你想引用一个不在尾部位置的递归时,你称它为"non tail recursive"
在您指定的代码中根本没有递归。所以,我建议你首先尝试编写 remove_if
函数并尝试弄清楚它是尾部还是非尾部。
更新
我通常尽量不为别人解决作业,但在这种情况下,我会通过为您提供 remove_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
因此,最后一个案例需要澄清一下:在 x
可以添加到 remove matches xs
的结果之前,需要评估后一个表达式。这意味着计算机需要将 x
存储在某处,以等到 remove matches xs
被计算。
所以,没有有趣的部分,你有一个非尾递归版本。现在,尝试递归地实现它。有fun
!
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
也许不是最好的,但它只删除了一个元素。
感谢大家的帮助。非常感谢。