我需要一个函数:
splitOn :: (Eq p) => p -> [p] -> ([p], [p])
所以:
splitOn 'b' ['a', 'b', 'b', 'b', 'c', 'a'] = (['a', 'b', 'b'], ['c', 'a'])
splitOn 'b' ['a', 'b', 'c', 'a'] = (['a'], ['c', 'a'])
传递的参数保证在中间的连续块中。
有没有办法在单次遍历列表时执行 splitOn
?
对不起,如果这是重复的,我找不到搜索它的方法。
答案 0 :(得分:1)
首先我们做这个,然后我们做那个,然后我们停止:
splitOn :: Eq a => a -> [a] -> ([a], [a])
splitOn b xs = g xs
where
g [] = ([], [])
g (x:xs) | x==b = f xs
| otherwise = first (x:) $ g xs
f [] = ([], [])
f (x:xs) | x==b = first (x:) $ f xs
| otherwise = ([], x:xs)
答案 1 :(得分:-1)
根据我的模糊理解,听起来您想将一组点存储在由第一个组件索引的有点平衡的二叉搜索树中。以现成的平衡二叉搜索树为例,它可能如下所示:
{-# LANGUAGE DeriveFoldable #-}
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as M
import Data.Set (Set)
import qualified Data.Set as S
-- | A `PointTree` stores, for each `a`, a set of second
-- components `b`.
newtype PointTree a b = PT
{ getPT :: Map a (Set b) }
fromList :: (Ord a, Ord b) => [(a, b)] -> PointTree a b
fromList = PT . M.fromListWith Set.union . map S.singleton
toList :: PointTree a b -> [(a, b)]
toList (PT m) = [(a, b) | (a, bs) <- M.assocs m, b <- S.elems bs]
以上将丢弃重复点。如果你想保留这些,你可以使用列表而不是集合。
现在,如果您想构建自己的平衡树,则必须选择一个。 Data.Map
和 Data.Set
使用亚当斯树(近似权重平衡)。您还可以使用 AVL 树、红黑树等。