【问题标题】:Functional map-like data structure with arbitrary length data as keys?具有任意长度数据作为键的类似地图的功能性数据结构?
【发布时间】:2011-08-04 01:33:35
【问题描述】:

这个问题的答案很可能是一个显而易见且响亮的“没有这样的事情”,但我会试一试:是否有一种功能性的类似地图的数据结构,它比当键具有任意的(通常非常大)大小时的标准映射?

为了具体起见,考虑 Haskell 类型

(Ord k) => Map [k] v

如果列表需要深入比较,查找可能需要很长时间。我猜由于列表的任意长度,散列也是不可能的。我仍然不禁想到那里可能有一个聪明的数据结构。

【问题讨论】:

  • 我怀疑使用 Vector(矢量包)而不是 List 作为关键将为此目的取得巨大的胜利。

标签: data-structures haskell map functional-programming


【解决方案1】:

散列是不可能的吗?没有可以高效计算的键结构前缀?

如果没有,hashmap 怎么样?取出非常大的键,将其缩减为非常小的值,将其用作结构的索引。

【讨论】:

  • 啊,你是对的。我想我正在错误地考虑任意大数据的哈希冲突。谢谢。
【解决方案2】:

试一试?

如果您有两个几乎相同的长键,则 Map 将从一开始就比较它们,但 trie 只会比较先前比较尚未消除的后缀(如果您明白我的意思) .因此,在这种情况下,trie 会更省时。

可以通过多种方式优化尝试,您可能还想查看三叉树。

【讨论】:

    【解决方案3】:

    这是一个:

    module ListMap where
    import Data.Map as M
    
    data ListMap k v = ListMap { ifEmpty :: Maybe v, ifFull :: Maybe k (ListMap k v) }
    
    empty :: ListMap k v
    empty = ListMap Nothing M.empty
    
    singleton :: [k] -> v -> ListMap k v
    singleton [] v = ListMap.empty { ifEmpty = Just v }
    singleton (k:ks) v = ListMap.empty { ifFull = M.singleton k (ListMap.singleton ks v) }
    
    lookup :: Ord k => [k] -> ListMap k v -> Maybe v
    lookup [] lm = ifEmpty lm
    lookup (k:ks) lm = M.lookup k (ifFull lm) >>= ListMap.lookup ks
    
    insert :: Ord k => [k] -> v -> ListMap k v -> ListMap k v
    insert [] v lm = lm { ifEmpty = Just v }
    insert (k:ks) v lm = lm { ifFull = M.alter (Just . insertion) k (ifFull lm) }
      where insertion = maybe (ListMap.singleton ks v) (ListMap.insert ks v)
    

    它本质上是在列表元素上创建一个前缀树,因此您只在必要时进行比较。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-02
      • 2019-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多