首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >"Problem9":打包列表

"Problem9":打包列表
EN

Stack Overflow用户
提问于 2013-02-14 06:40:27
回答 2查看 316关注 0票数 1

我在没有任何函数式编程背景的情况下学习f# -开始取得进展,但在这一点上停滞不前。有人能帮助我理解99个f#问题中的问题9的解决方案吗?他们可以在这里找到:http://fssnip.net/an

基本上,我不理解模式匹配在所提供的解决方案中是如何工作的。首先,什么是xss?为任何帮助干杯!

问题9:将列表元素的连续副本打包到子列表中。如果列表包含重复的元素,则应将它们放在单独的子列表中。

示例:

压缩'a';'b';'c';'c';'a';'a';'d';'e';'e‘

val it : char list list = ['a';'b';'c';'c';'a';'a';'d';'e';'e']

样本解决方案;

代码语言:javascript
复制
let pack xs = 
    let collect x = function
        | (y::xs)::xss when x = y -> (x::y::xs)::xss
        | xss -> [x]::xss
    List.foldBack collect xs []
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-02-14 06:58:51

要理解这一点,首先要了解列表在F#中是如何表示的。F#列表可以是:

  • 一个空列表,写为[]
  • 一个值(head),后跟另一个写为head::tail

的列表(尾

因此,例如,如果您编写[ 1; 2; 3 ],您实际上是在构造一个包含1的列表,后跟一个包含2的列表,(依此类推)后面跟着一个空列表。该表达式被编译为:

代码语言:javascript
复制
1::(2::(3::[])) 

您可以省略括号,只编写1::2::3::[]

模式匹配使用完全相同的语法,但方向相反。你不是在构造列表,而是分解它们。因此,当您有一个模式x::xs时,这意味着您希望获取第一个元素并将其赋给一个变量x,而剩余的列表应该赋值给一个变量xs

模式(x::xs)::xss稍微有点棘手,因为它适用于列表列表。这意味着您匹配的列表的头部也是一个列表。您可以将代码重写为以下更简单的版本:

代码语言:javascript
复制
let pack xs = 
    let collect x = function
        | head::xss ->    // Decompose into first element (head) and the rest (tail)
          match head with
          | y::xs when x = y -> (x::y::xs)::xss
          | _ -> [x]::xss
        | xss -> [x]::xss
    List.foldBack collect xs []

现在您在代码中有了一些重复,但是您可以看到collect接受x和另一个参数,将另一个参数与head::xss进行匹配(以获得头部/尾部),然后也分解head

票数 1
EN

Stack Overflow用户

发布于 2013-02-14 06:49:01

(y::xs)::xss匹配列表的(非空)列表,yxs是第一个子列表的头部和尾部,xss是外部列表的尾部。在第二种情况下,xss匹配整个列表(无论是否为空)。

foldBack (('T -> 'State -> 'State) -> 'T list -> 'State -> 'State)将累加器参数从后到前遍历列表。

collect是“累加”函数,它基本上是这样的:如果状态(最初是一个空列表)包含至少一个子列表,该子列表也是非空的,并且当前元素(x)与子列表(y)的头部匹配,则将x附加到子列表,否则将新的子列表附加到仅由x组成的状态(xss)。每个子列表是一组相等的相邻元素。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14864631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档