list - 子列表操作

标签 list recursion f#

我目前想知道一种根据给定标准将列表拆分为子列表的方法。由于这项工作的教学目的,我不使用内置函数。 IE,下面的程序应该,给定一个列表,返回一个列表的列表,其中每个子列表没有重复并且按升序排列:

increment [4;4;10;20;5;30;6;10] = [[4;10;20];[5;30];[6;10]]
increment [5;6;4;3;2;1] = [[5;6];[4];[3];[2];[1]]

到目前为止,我最好的尝试是基于我生成的这段代码:

let rec increment li [lo] = 
    match li with
        |[]         ->  [lo]
        |[x]        ->  [x]::[lo]
        |x::y::xs   ->  if x = y then
                            increment (y::xs) [lo]
                        elif x < y then
                            x::(increment (y::xs) [lo])
                        else
                            (x::(increment xs [lo]))::[lo]

不幸的是,我未能创建列表列表。原理是正确的。它基于我构建的函数,如果存在则正确隔离升序列表:

let rec incrementAux li = 
    match li with
        |[]         ->  []
        |[x]        ->  [x]
        |x::y::xs   ->  if x = y then
                            incrementAux (y::xs)
                        elif x < y then
                            x::(incrementAux (y::xs))
                        else
                            x::(incrementAux [])

如有任何建议,我们将不胜感激!

最佳答案

如果你想在不使用 List 模块上的内置函数的情况下执行此操作(纯粹作为学习练习),那么你只需要了解 mapfold 以便您可以自己实现它们。我将从 this wikipedia article 开始.方便的是,您可以根据 fold 轻松实现 rev,所以这应该不是问题。了解每个函数的作用后,您可以像这样自己实现它们:

let rec fold f state = function
| [] -> state
| head::tail -> fold f (f state head) tail

let map f list =
    [for item in list -> f item]

let rev list = 
    fold (fun acc cur -> cur::acc) [] list

然后,您可以用自己的函数替换 Szer 解决方案中的内置函数:

let input = [4;4;10;20;5;30;6;10]
let output = [[4;10;20];[5;30];[6;10]]

let increment = 
    fold (fun (last::rest as total) x ->
        match last with
        | [] -> [x] :: rest
        | h::_ as last ->
        if x > h then (x::last)::rest
        else if x = h then total
        else [x]::total) [[]]
    >> map rev
    >> rev

let testOutput = increment input
testOutput = output

请注意,fold 的实现与 F# List 的实现方式不同。这是基于维基百科文章中的简单 Haskell 示例。功能相同,但实现却大不相同,因为 F# 实际上使用可变累加器和 for 循环。

关于list - 子列表操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50405408/

相关文章:

python - 为什么代码创建的列表不包含大于 99,999 的值 (Python)

java - 二维迷宫的递归算法?

c# - 值等于和循环引用 : how to resolve infinite recursion?

java - 如何查找 ASTNode 的所有子节点(子节点和子节点的子节点)

python - 为什么多个 list.count 调用比单个循环更快?

c# - 优化的通用列表拆分

python-3.x - 如何按我的顺序对列表进行多次排序?

.net - 在具有元组的可区分联合上重载相等 F# 运算符会产生意外结果

types - 如何直接在 Measure 类型本身上通过静态成员 New 生成 bool 成员类型?

.net-core - FSharp 出现错误 : error FS0192 the anonymous record <>f__AnonymousType has not been generated in the pre-phase of generating this module