首页 > 解决方案 > 如何计算 OCaml 中任何元素类型列表中连续出现的次数?

问题描述

在 OCaml 中,假设我有一个字符串列表,如下所示:

let ls : string list = ["A"; "A"; "B"; "B"; "A"; "Y"; "Y"; "Y"] ;;

我在编写一个函数来计算一个元素连续出现的次数并将该元素与其频率配对时遇到了麻烦。例如,给定上面的列表作为输入,函数应该返回[("A", 2); ("B", 2), ("A", 1), ("Y", 3)].

我尝试在其他地方寻找一些提示,但几乎所有其他类似的操作都是使用int lists 完成的,在这里很容易将数字相加。但是在这里,我们不能添加字符串。

我的直觉是以fold_left类似的方式使用类似的东西,如下所示:

let lis : int list = [1;2;3;4;5]
let count (lis : int list) = List.fold_left (fun x y -> x + y) (0) (lis)

这本质上是从左到右累积所有元素的总和。但是,就我而言,我不想累计所有元素,我只需要计算一个元素连续出现的次数。一些建议将不胜感激!

标签: listocaml

解决方案


这显然是一个家庭作业,所以我只给出一些提示。

当您的代码工作时,它不会将字符串(或任何其他类型)添加在一起。它将把整数加在一起。所以你可能想再次回顾一下网上的那些例子:-)

你绝对可以用fold_left得到答案。首先,请注意 resultl 是对的列表。每对的第一个元素可以是任何类型,具体取决于原始列表的类型。每对中的第二个元素是一个 int。所以你有一个你正在使用的基本类型:('a * int) list.

想象一下,你有办法“增加”这样一个列表:

let increment (list: ('a * int) list) value =
     (* This is one way to think of your problem *)

此函数在列表中查找第一个元素等于 value 的对。如果找到它,它会返回一个新列表,其中关联的 int 比以前大一。如果它没有找到它,它会返回一个带有额外元素的新列表(value, 1)

这是您要折叠列表的基本操作,而不是+您的示例代码的操作。


推荐阅读