【问题标题】:Check list for consecutive values within range (F#)范围内连续值的检查列表 (F#)
【发布时间】:2014-01-25 03:41:31
【问题描述】:

在 10 个数字的排序列表中,我想找出是否有 5 个连续的数字在一定范围内。供参考:这称为寻找“stellium”(天文术语,关于行星的位置)。

如果列表是:

let iList = [15; 70; 72; 75; 80; 81; 120; 225; 250; 260]

我想要一个函数

let hasStellium iStellSize iStellRange iList

这将返回

hasStellium 5 20 iList = true

列表已经排序,所以我可以继续使用笨拙的 if-then 语句(例如“检查元素 1 和 5 是否相距小于 20 个单位,检查元素 2 和 6 是否满足条件”等。

let hasStellium iStellSize iStellRange iList=
        if 
             iList.[iStellSize-1] - iList.[0] < iStellRange ||
             iList.[iStellSize] - iList.[1] < iStellRange
        then true 
        else false

但必须有一种更优雅的方式,它还允许其他 stellium 大小,而无需手动添加 if-then 行。

非常感谢您的帮助!

(如果函数可以返回群开始的索引号,那就更好了)

【问题讨论】:

    标签: list f#


    【解决方案1】:

    只需结合两个标准库函数:

    let hasStellium iStellSize iStellRange iList =
        iList |> Seq.windowed iStellSize
        |> Seq.tryFindIndex (fun s -> (s.[iStellSize - 1] - s.[0] < iStellRange))
    

    如果找不到这样的范围,则返回None,否则返回Some x,其中x - 范围开始索引。

    【讨论】:

    • 非常感谢,太好了! :-)
    【解决方案2】:

    给你。它返回一个int option,它是范围的起始索引,如果没有找到则返回None

    let tryFindStelliumIndex iStellSize iStellRange iList =
      let rec findRange i n = function
        | _ when (n + 1) = iStellSize -> Some (i - n)
        | prev::cur::tail when (cur - prev) < iStellRange -> findRange (i + 1) (n + 1) (cur::tail)
        | _::tail -> findRange (i + 1) 0 tail
        | _ -> None
      findRange 0 0 iList
    

    【讨论】:

      【解决方案3】:

      使用 Seq 函数的另一种变体:

      let hasStellium size range l = 
          Seq.zip l (l |> Seq.skip (size - 1)) 
       |> Seq.tryFindIndex (fun p -> snd p - fst p < range)
      

      【讨论】:

        【解决方案4】:

        不得不用可变变量破解“提前返回”,但这是一个粗略的版本

        let mutable found = false
        for i = 0 to (iList |> List.length - iStellSize) do
            if iList.[i + iStellSize] - iList.[i] <= iStellRange then //Did you mean < or <=?
               found <- true
        found
        

        【讨论】:

          猜你喜欢
          • 2021-11-21
          • 1970-01-01
          • 1970-01-01
          • 2011-01-17
          • 2022-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多