haskell - 获取满足条件的最短列表前缀
问题描述
假设我有一个列表,并且想要获取列表的最短前缀以满足条件。例如,假设我想获得一个整数列表的前缀,其总和至少为给定数字。一种方法:
module ListPrefix where
import Data.Maybe
lpref :: Int -> [Int] -> Maybe [Int]
lpref w xs =
let f l r s
| s >= w = Just (reverse l)
| null r = Nothing
| otherwise = f (head r : l) (tail r) (s + head r)
in f [] xs 0
main = do
print $ lpref 48 [1..100]
有没有办法在不使用手动递归的情况下编写这个?
编辑:
根据Willem的建议,一个更好的版本:
lpref2 :: Int -> [Int] -> Maybe [Int]
lpref2 w xs =
let f t@(ys, s) e = if s >= w then t else (e : ys, s + e)
(fs, s) = foldl f ([], 0) xs
in if s >= w then Just (reverse fs) else Nothing
让我知道这是否可以改进!
解决方案
这是一个简单、简洁的方法,虽然可能不是最有效的:
import Data.List (find, inits)
lpref :: Int -> [Int] -> Maybe [Int]
lpref w = find (\xs -> sum xs >= w) . inits
至于您的尝试,首先要注意的是,在常规列表中,foldl
总是错误的。您应该始终使用foldl'
或foldr
代替。此外,测试null
然后使用head
andtail
作为反模式。
为了最大限度地提高效率,我会采取以下措施:
lpref :: Int -> [Int] -> Maybe [Int]
lpref w xs
| 0 >= w = Just []
| otherwise = foldr go mempty xs 0 id
where
go :: Int -> (Int -> ([Int] -> [Int]) -> Maybe [Int]) -> Int -> ([Int] -> [Int]) -> Maybe [Int]
go x acc s f
| s' >= w = Just $ f [x]
| otherwise = acc s' (f . (x:))
where s' = x + s
这也是最大的懒惰。lpref 6 (1:2:3:undefined)
返回Just [1,2,3]
。
推荐阅读
- python - AttributeError:模块“PIL”没有属性图像
- python - Matplotlib 不在 Databricks 上打印任何图?
- python-3.x - psycopg2.errors.InvalidFunctionDefinition:创建函数必须指定波动属性(IMMUTABLE|STABLE|VOLATILE)
- python - 如何将最终的密集层写入“接受”(x,y)元组
- java - 初始化中带有 Spring Boot 模拟 bean 的模拟返回 null
- swiftui - 当 ForEach 方法生成的某些值发生更改时,如何重新加载视图屏幕?
- powershell - 在 Windows Powershell 中使用相当于“source”的命令激活虚拟环境
- python - Python:Keras 模型为相同的数据和相同的模型返回不同的结果
- python - Python - 使用 TAPI(电话应用程序编程接口)拨打电话
- wordpress - 在 wordpress 安装之间共享用户登录