比较列表F#中子列表的长度

时间:2018-10-07 10:02:33

标签: f#

我是F#的新手,目前正在研究一个问题,在这个问题中,我试图比较列表中子列表的长度,并返回一个布尔值。

如果任何子列表为空,则该程序还应返回“ false”。但是,尽管我一直在进步,但我仍然无法解决当前的问题,即使我以某种方式知道出了什么问题(这与到目前为止的F#语言经验相关)。希望有人可以帮我忙,以便我可以快速进行下一个项目。

到目前为止,我的程序如下:

let projectOne (initList: int list list) =
let mutable lst = initList.[0].Length
let mutable lst1 = ""
let n = initList.Length
for i=1 to n-1 do
    if lst = 0 || initList.[i].Length = 0 then
        lst1 <- "false"
    elif lst <> initList.[i].Length then
        lst1 <- "false"
    elif
        lst = initList.[i].Length then 
        lst1 <- "true"
lst1

printfn "The sublists are of same lenght: %A" (projectOne [[1;2;3;4];[4;5;6];[6;7;8;9];[5;6;7;8]])

我看到的方式是,现在我将[0]与[i]在循环中每次迭代递增时进行比较,这会导致打印示例出现问题,我通过比较[0]结束迭代与[3]相同,由于2个子列表的大小相等,因此我的函数返回“ true”,这显然是错误的,因为[1]的长度比其余的短,因此结果应为“ false”。

我尝试通过对每次迭代更改lst的值来解决此问题,但是如果例如[2]和[3]的长度相同,但[0]和[1]的长度相同,这又会引起问题,即使输出应为“ false”,它也会再次返回“ true”。 (例如[[1; 2; 3]; [3; 4; 5]; [6; 7]; [8; 9]])

我似乎无法将自己的思绪笼罩在怀念的事物上。由于我无法中断F#中的循环(至少不能像Python这样的传统方式),因此我需要运行所有迭代,但是我希望每次迭代都可以与所有先前子列表长度的平均值进行比较(如果有意义)

我想念什么? :-)我虽然可以使用af List.fold运算符来解决此问题,但不确定该如何实现,因为程序还需要检查空列表。

我可以说,但是我正在尝试使用适合我目前水平和经验的方法来解决问题。我确信可以使用管道运算符|>提供一些非常紧凑的解决方案,但是我还不能使用这些解决方案,因此我正在寻找一个更简单的perhabs初学者解决方案。

谢谢。

3 个答案:

答案 0 :(得分:3)

一种更实用的思考方式是

  1. 如果所有子列表都为空,则它们的长度都相同
  2. 否则,如果任何子列表为空,则它们的长度不相同
  3. 否则,如果列表的尾部都相同,则它们的长度也相同

例如:

let rec projectOne initList =
    if List.forall List.isEmpty initList then
        true
    else if List.exists List.isEmpty initList then
        false
    else
        projectOne (List.map List.tail initList)

答案 1 :(得分:0)

这是另一种方法:

let projectOne lst =
    match lst with
    | h::t -> t |> List.forall(fun (l:_ list) -> l.Length = h.Length)
    | _    -> true

答案 2 :(得分:0)

您的代码的简单修复方法可能是:

let projectOne (initList: int list list) =
    let length = initList.[0].Length
    let mutable result = length <> 0
    let n = initList.Length

    for i=1 to n-1 do
        result <- result && initList.[i].Length = length

    result

它仍然在可变变量上运行,这在函数编程中是不希望的,并且效率低下,即使找到了错误的长度,它也会搜索所有列表。


另一个-更具功能性-解决方案可能是:

let haveEqualLength lists =
    let length = lists |> List.head |> List.length
    length <> 0 && lists |> List.tail |> List.tryFind (fun l -> l.Length <> length) = None