Lambda 列表中最小的索引i,使得从0到i的数组元素的前缀和小于F中的某个常数c#
假设列表由正数组成 我可以做一个部分求和,用{0..n}压缩它,并在上面运行一些东西,但它感觉很笨拙,并且没有惰性 递归lambda可能会更好,但我不确定递归lambda是否可行,我觉得必须有非常干净的解决方案 例如: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]
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。谢谢!会再等一段时间并接受它:)