使用 OCAML 返回没有最后一个元素的列表

问题描述 投票:0回答:2

使用 OCAML,我需要返回一个没有最后一个元素的列表,例如像 ["one" ; 这样的字符串列表。 “二” ; "三"] 必须显示 ["一" ; "two"],仅适用于预定义函数 List.hd、List.tl 或 List.length。任何人都可以帮助我吗?谢谢。 我所做的,根本不起作用:

let rec remove_last l =
    match l with
    | [] -> []
    | head :: tail when n = 0 -> tail
    | head :: tail -> head :: (remove (n - 1) tail);;

remove_last l ["one" ; "two" ; "three"];;
ocaml
2个回答
0
投票

你说你需要一个解决方案 with List.hd, List.tl, List.length。但我很确定您需要一个解决方案 without 这些内置功能。这是通常的要求,因为这意味着您必须使用基本的语言功能(模式匹配和递归)。

您的代码使用名为

remove
的函数和名为
n
的变量,但没有在任何地方定义函数
remove
或变量
n
。因此,您的代码无法正常工作是合理的。

解决问题的一种方法是使用列表的长度,但是您需要在不使用

List.length
的情况下计算列表的长度。

在我看来,与其定义自己的长度函数,还不如直接使用模式和递归来解决问题。列表的末尾将是这样的模式

[_]
,其中
_
匹配列表的最后一个元素。如果你看到这个模式,结果列表应该是空的
[]
,即最后一个元素被删除。

如果您递归地思考,您会发现基本情况是长度为 0(您在代码中正确处理)或长度为 1(如上所述处理)的列表。任何其他列表都可以通过将列表的头部添加到列表尾部的缩短版本来递归处理。

希望对您有所帮助。我不想给你写代码,因为这是一项任务。


0
投票

如果你只使用模式匹配,那么你可以直接考虑特定模式会导致什么:

  • 如果给我们一个空列表,可能会引发异常。
  • 如果是单个元素,则为空列表。
  • 如果一个列表有 two 元素,你只需要第一个。
  • 如果你有两个以上的元素,它可能是第一个元素附加到从列表尾部删除最后一个元素的结果。

现在,如果您必须只使用

List.hd
List.tl
List.length
,您可以通过首先计算原始列表的长度,然后定义一个跟踪索引并仅收集元素的辅助函数来完成此操作来自原始列表,而索引小于长度减一。

该函数的基本形式可能如下所示。

let remove_last lst =
  let len = ... in
  let rec aux i lst =
    if i < len - 1 then ...
    else ...
  in
  aux ... lst
© www.soinside.com 2019 - 2024. All rights reserved.