List Haskell得到一个过滤过的整数列表

List Haskell得到一个过滤过的整数列表,list,haskell,filter,List,Haskell,Filter,情景: 如果有一个整数数组,我想得到一个整数数组作为回报,它们的总数不应该超过10 我是Haskell的初学者,在下面尝试过。如果有人能纠正我,我将不胜感激 numbers :: [Int] numbers = [1,2,3,4,5,6,7,8,9,10, 11, 12] getUpTo :: [Int] -> Int -> [Int] getUpTo (x:xs) max = if max <= 10 then max = max +

情景: 如果有一个整数数组,我想得到一个整数数组作为回报,它们的总数不应该超过10

我是Haskell的初学者,在下面尝试过。如果有人能纠正我,我将不胜感激

numbers :: [Int]
numbers = [1,2,3,4,5,6,7,8,9,10, 11, 12]

getUpTo :: [Int] -> Int -> [Int]
getUpTo (x:xs) max =
    if max <= 10
    then
            max = max + x
            getUpTo xs max
    else
            x
预期产量

[1,2,3,4]

注意:这不是背包问题的解决方案:)

我提出的一个非常快速的解决方案是下面的一个。当然,解决完整背包问题会更加困难,但如果您只需要快速解决方案,这应该可以:

import Data.List (sort)

getUpTo :: Int -> [Int] -> [Int]
getUpTo max xs = go (sort xs) 0 []
    where
        go [] sum acc         = acc
        go (x:xs) sum acc
            | x + sum <= max  = go xs (x + sum) (x:acc)
            | otherwise       = acc
导入数据列表(排序)
getUpTo::Int->[Int]->[Int]
getUpTo max xs=go(sort xs)0[]
哪里
go[]和acc=acc
go(x:xs)和acc

|x+sum有一个快速版本的答案;然而,我认为看到对代码进行必要的最小更改以使其按预期的方式工作也可能是有益的

numbers :: [Int]
numbers = [1,2,3,4,5,6,7,8,9,10, 11, 12]

getUpTo :: [Int] -> Int -> [Int]
getUpTo (x:xs) max =
    if max < 10 -- (<), not (<=)
    then
            -- return a list that still contains x;
            -- can't reassign to max, but can send a
            -- different value on to the next
            -- iteration of getUpTo
            x : getUpTo xs (max + x)
    else
            [] -- don't want to return any more values here
数字::[Int]
数字=[1,2,3,4,5,6,7,8,9,10,11,12]
getUpTo::[Int]->Int->[Int]
getUpTo(x:xs)最大值=
如果max<10——(出于教育目的(因为我想解释一下:-),这里有一个不同的版本,它使用了更多的标准函数。编写时速度较慢,因为它计算了大量的和,并且没有保持一个连续的总数。另一方面,我认为它很好地表达了如何分解问题

getUpTo :: [Int] -> [Int]
getUpTo = last . filter (\xs -> sum xs <= 10) . Data.List.inits
getUpTo::[Int]->[Int]

getUpTo=last.filter(\xs->sum-xs-sum-xs-sum-xs==10).Data.List.inits
。或者如果您想查看尾段,请使用
head.filter(\xs->sum-xs-sum-xs-length-xs
比较
长度ys.).Control.Monad.filterM(const[False,True])
-但我不打算在这里解释,我已经说得够久了!

我对Haskell是相当陌生的。我几个小时前才开始使用它,因此我在每个问题上都看到了一个挑战,帮助我摆脱了命令式思维方式,并有机会练习递归思维:)

我对这个问题进行了一些思考,并提出了一个可能是幼稚的解决方案:

upToBound :: (Integral a) => [a] -> a -> [a]
upToBound (x:xs) bound = 
        let
                summation _ []  = []
                summation n (m:ms)  
                        | n + m <= bound = m:summation (n + m) ms 
                        | otherwise = []
        in
                summation 0 (x:xs)                

其输出:
[1,2,3,4]

请指定“整数数组”。连续的允许有洞吗?独特的解决方案?最佳解决方案(wrt to what means“Best”)?例如,
[4,6]
是对
获取数字的可接受答案吗?为什么,或者为什么不?我不知道你的问题是什么对不起:(@Randy:你是在解决背包问题,还是函数只需要计算满足你约束条件的第一个解(不管是什么)?我想你指的是“列表”,而不是“数组”.在Haskell中,它们是完全不同的,通常不使用数组。这正是我想要的。我知道这不是背包的解决方案,这只是我为了理解问题和学习如何解决问题而做的一个小测试。非常感谢!嗨,结果返回一个空列表。不太清楚原因:(@Randy你是否使用了
getUpTo number 0
,就像你的问题说你想用它作为输入?;-)一个更有效的简单方法是在使用
takeWhile
之前使用
scanl1(+)
zip
原始列表获取部分和:
getUpTo xs=map fst.takeWhile((@hammar:我也想过解释类似的东西(但更笨拙,压缩
scanl(+)0 xs
inits xs
),但我想保持它的基本性。相反,我选择炫耀我最喜欢的Haskell魔法(用
filterM
生成所有子列表)。啊,我的版本或多或少是无意义的:-)
upToBound :: (Integral a) => [a] -> a -> [a]
upToBound (x:xs) bound = 
        let
                summation _ []  = []
                summation n (m:ms)  
                        | n + m <= bound = m:summation (n + m) ms 
                        | otherwise = []
        in
                summation 0 (x:xs)                
upToBound [1,2,3,4,5,6,7,8,9,0] 10