Lambda 列表中最小的索引i,使得从0到i的数组元素的前缀和小于F中的某个常数c#

Lambda 列表中最小的索引i,使得从0到i的数组元素的前缀和小于F中的某个常数c#,lambda,f#,functional-programming,Lambda,F#,Functional Programming,假设列表由正数组成 我可以做一个部分求和,用{0..n}压缩它,并在上面运行一些东西,但它感觉很笨拙,并且没有惰性 递归lambda可能会更好,但我不确定递归lambda是否可行,我觉得必须有非常干净的解决方案 例如: list [2;2;3;4;5] c = 5 partial sums [2;4;7;11;16] => return 1(because a[1] = 4 <= c < a[2] = 7) 列表[2;2;3;4;5] c=5 部分和[2;4;7;11;16]

假设列表由正数组成

我可以做一个部分求和,用{0..n}压缩它,并在上面运行一些东西,但它感觉很笨拙,并且没有惰性

递归lambda可能会更好,但我不确定递归lambda是否可行,我觉得必须有非常干净的解决方案

例如:

list [2;2;3;4;5]
c = 5
partial sums [2;4;7;11;16] => return 1(because a[1] = 4 <= c < a[2] = 7)
列表[2;2;3;4;5]
c=5

部分和[2;4;7;11;16]=>返回1(因为[1]=4在haskell中您需要类似于
scanl
takeWhile
的内容。然后您可以执行以下操作:

let sums = takeWhile (<c) (scanl (+) 0 original)
in length sums - 1

let sums=takeWhile(您可以使用
Seq.findIndex
并保持一个运行总数,如下所示:

let smallestIndexWhileSumIsUnder maxSum seq =
    let sum = ref 0
    let indexWhereSumIsTooMuch =
        seq
        |> Seq.findIndex (fun i ->
            sum := !sum + i
            !sum >= maxSum
        )
    indexWhereSumIsTooMuch - 1
用法:

smallestIndexWhileSumIsUnder 10 [1; 2; 3; 4; 5; 6]
takeWhileSumIsUnder 10 [1; 2; 3; 4; 5; 6]
结果:

2
seq [1; 2; 3]

或者,如果您想要的是序列本身,您可以使用
Seq.takeWhile
并按如下方式执行:

let takeWhileSumIsUnder maxSum seq =
    let sum = ref 0
    seq
    |> Seq.takeWhile (fun i ->
        sum := !sum + i
        !sum < maxSum
    )
结果:

2
seq [1; 2; 3]

最小的索引是
i=0
。除非您指的是最大的
i
,否则这里有一个使用模式匹配的递归算法。请注意,我不允许索引小于0:

let rec smallestIndexRecursive sumTotal currIndex maxSum list =
    match list with
    | [] -> currIndex
    | head::tail -> match head with
                    | head when (head + sumTotal) < maxSum -> 
                    smallestIndexRecursive  (head + sumTotal) (currIndex + 1) maxSum tail
                    | _ when currIndex <= 0 -> 0
                    | _ -> currIndex - 1

smallestIndexRecursive 0 0 maxSum list

你已经尝试自己解决这个问题了吗?是的,我用递归函数(第3段)解决了问题,并考虑了部分和和和范围压缩(参考图2),但无法用谷歌搜索一个最好的干净的方法来解决这个问题。真棒,f#中也有takeWhile。谢谢!会再等一段时间并接受它:)