给定[1,0,0,0,3,0,0,0,0,2,4,0,0]
等列表和索引,如何在Haskell中提取连续的0模式。例如,如果给定索引介于1和3之间,则结果为[0,0,0]
,如果介于5和8 [0,0,0,0]
之间,依此类推
答案 0 :(得分:1)
首先,构建一个列表,其中为每个数字存储运行长度:
runs :: (Eq a) => [a] -> [(a, Int)]
runs = map (head &&& length) . group
所以,例如
runs [1,0,0,0,1,0,0,0,0,1,1,0,0] == [(1,1),(0,3),(1,1),(0,4),(1,2),(0,2)]
然后,通过以运行长度大小的步骤进行索引来索引此列表:
indexRuns :: Int -> [(a, Int)] -> [a]
indexRuns i [] = error "Index out of bounds"
indexRuns i ((x, l):rs)
| i < l = replicate l x
| otherwise = indexRuns (i - l) rs
答案 1 :(得分:0)
这将计算索引周围的零数
numZeros::Int->[Int]->Int
numZeros 0 (1:_) = 0
numZeros i (1:rest) = numZeros (i-1) rest
numZeros i theList
| i < zeroLen = zeroLen
| otherwise = numZeros (i-zeroLen) $ drop zeroLen theList
where
zeroLen = length (takeWhile (==0) theList)
您可以复制0
适当的次数以获得最终列表。
答案 2 :(得分:0)
您可以在O(n)时间内完成此操作:
extract :: Eq a => Int -> [a] -> [a]
extract _ [] = []
extract idx (x:xs) = extract' x [x] 1 xs
where
extract' _ _ _ [] = [] -- Index out of bounds
extract' v vs n (r : rest)
| idx == n = vs ++ (takeWhile (== v) rest)
| (v == r) = extract' v (r:vs) (n+1) rest
| otherwise = extract' r [r] (n+1) rest
答案 3 :(得分:0)
f = f' (takeWhile (== 0)) where
f' c n xs | n < 0 || null xs = []
f' c n (1:xs) = f (n - 1) xs
f' c 0 xs = c xs
f' c n (0:xs) = f' ((0:) . c) (n - 1) xs
甚至更加模糊
f n xs = g (splitAt n xs) >>= takeWhile (== 0) where
g (xs, ys@(0:_)) = [reverse xs, ys]
g _ = []
一些测试:
main = mapM_ (\i -> print $ (i, f i [1,0,0,0,1,0,0,0,0,1,1,0,0])) [-1..13]
打印
(-1,[])
(0,[])
(1,[0,0,0])
(2,[0,0,0])
(3,[0,0,0])
(4,[])
(5,[0,0,0,0])
(6,[0,0,0,0])
(7,[0,0,0,0])
(8,[0,0,0,0])
(9,[])
(10,[])
(11,[0,0])
(12,[0,0])
(13,[])