繁体   English   中英

当n适合谓词时,删除Haskell列表中位置n和n-1处的元素

[英]Remove elements at positions n and n-1 in a Haskell list, when n fits a predicate

假设我有一个从220的所有整数的列表。

[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20]

我还有一个返回TrueFalse的函数fx 当我将这个函数应用于位置n的元素并且它等于True ,我想删除它及其先前元素(它是位置n-1处的元素)。 我想继续这样做,直到列表中没有函数等于True的元素,以及它们的前面元素。

示例:假设位置11的元素(等于13 )符合谓词。 然后我想删除位置10处的元素,该元素等于12 之后我的最终名单将是:

[2,3,4,5,6,7,8,9,10,11,14,15,16,17,18,19,20]

我们还假设,在位置上的元件48以及15是唯一的元素(除了在位置上的元素13适合谓词)。 删除它们及其前面的元素后,我的最终列表将如下所示:

[2,3,4,7,8,11,14,15,18,19,20]

我是一个没有经验的Haskell程序员,只是为了好玩而玩。 我想过使用某种lambda函数作为过滤器的谓词,或者创建像listRemove xs ys这样的函数来删除xs所有元素,这些元素也是ys的元素,但我觉得两者都丢失了。

任何帮助,将不胜感激!

编辑:我想要做的是解决项目欧拉问题,即#179 谓词fx是检查x是否是素数。 因此,我可以肯定地说没有存在边角情况 - 例如,没有诸如[x, x, t, t] ,其中t是谓词所持有的数字,因为不存在两个连续的整数,这两个整数都是素数除外对于23 ,我可以在我的解决方案中轻松处理。 相反,你可以得到的最接近的是[x, t, x, t] ,在这种情况下,我想删除所有这些元素。

解决了 “当n符合谓词时,删除Haskell列表中位置n和n-1处的元素”

filter' :: (a -> Bool) -> [a] -> [a]
filter' f xs = map (\i -> xs!!i) $
                 [i | i <- [0 .. s], fit i && (i >= s || fit (i+1))]
               where s = length xs - 1
                     fit i = not (f (xs!!i))

用法

*Main> filter' (==4) [1,2,3,4,5,6]
[1,2,5,6]

*Main> filter' (\n -> n `mod` 7 == 0) [1..23]
[1,2,3,4,5,8,9,10,11,12,15,16,17,18,19,22,23]

*Main> filter' (\n -> n `elem` [4,5,6]) [1..10]
[1,2,7,8,9,10]

O(n)成本可能

filter' :: (a -> Bool) -> [a] -> ([a], Bool)
filter' _  [] = ([], False)
filter' f [x] = if f x then ([], True) else ([x], False)
filter' f (y:xs) = case filter' f xs of
                    (xs', True)  -> (xs', f y)
                    (xs', False) -> if f y then (xs', True) else (y:xs', False)

使用标准功能

filter' f xs = filter (not.f) $ map fst $ filter (not.f.snd) $ zip xs $ tail xs ++ [last xs]

假设你有:

disallowed :: Int -> bool
-- A function that matches your example
disallowed x = elem x [6, 10, 13, 17]

你想要的只是

import Data.List (tails)

map head . filter (not . any disallowed . take 2) . filter (not . null) . tails $ [2..20]

如果你想给它一个名字:

filterWithTails :: ([a] -> Bool) -> [a] -> [a]
filterWithTails f = map head . filter f . filter (not . null) . tails

filterWithTails (not . any disallowed . take 2) [2..20]

(not . any disallowed . take 2)是你想要在过滤时考虑列表的其余部分来过滤列表的方式。 提供一个比构成函数的组合更好的名称是很难的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM