【问题标题】:Why doesn't Data.Sequence have `insert' or `insertBy', and how do I efficiently implement them?为什么 Data.Sequence 没有“insert”或“insertBy”,我如何有效地实现它们?
【发布时间】:2011-06-20 21:45:31
【问题描述】:

我对 Sequence 类型的接口中缺少这些函数感到困惑,因为 Data.List 提供了这些函数。这里是效率问题,还是只是对这些功能的需求不足?

由于它们不是 Data.Sequence 的一部分,我如何才能有效地实现它们以达到我的目的?

【问题讨论】:

  • 它不像Data.List那么完整,但是Sequence 接口严重依赖于类型类。 map 来自Functorfold 来自Foldable 等。你也可以使用 ListLike,hackage.haskell.org/package/ListLike,它有一个 Sequence 类型的实例,会给你一个更完整的接口,包括insertinsertBy;我觉得界面和米哈伊尔的第二个例子一样。

标签: haskell containers


【解决方案1】:

这是我想出的:

> let insertBy cmp x seq = let (s1,s2) = partition (\y -> cmp x y == GT) seq in (s1 |> x) >< s2
> let s = fromList [1,2,3,4,5]
> insertBy compare 2 s
fromList [1,2,2,3,4,5]

或者你可以模仿列表的版本:

{-# LANGUAGE ViewPatterns #-}

module Main
    where

import Data.Sequence

insertBy :: (a -> a -> Ordering) -> a -> Seq a -> Seq a
insertBy _   x (viewl -> EmptyL) = singleton x
insertBy cmp x ys@(viewl -> (y:<ys'))
 = case cmp x y of
     GT -> y <| insertBy cmp x ys'
     _  -> x <| ys

【讨论】:

  • 我想这基本上和最快的方法一样快。我将把这个答案标记为正确,因为我刚刚意识到我需要的不仅仅是序列,我需要强制执行序列总是有序的不变量,这样我就可以在 O(log n) 时间而不是 O( n) 时间。
  • @danharaj,是否考虑过 Data.Set?
  • @luqui,我有,但是在我正在实施的算法过程中我的排序发生了变化,Bentley-Ottmann 供参考。由于订单关系发生变化,我无法使用 Data.Set。但是,顺序会以一种行为方式发生变化,因此二进制搜索是可行的方法。
猜你喜欢
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 1970-01-01
  • 2018-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多