具有任意长度数据作为键的功能性地图式数据结构?

时间:2011-04-12 16:36:41

标签: data-structures haskell map functional-programming

很可能这个问题的答案显然是响亮的“没有这样的事情”,但我会试一试:是否有一个功能性的地图式数据结构比一个更有效标准地图当钥匙有任意的,往往很大的尺寸?

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

(Ord k) => Map [k] v

如果需要将列表进行深层比较,则查找可能需要很长时间。由于列表的任意长度,我想哈希也是不可能的。我仍然情不自禁地认为那里可能有一个聪明的数据结构。

3 个答案:

答案 0 :(得分:6)

哈希是不可能的?密钥结构没有可以有效计算的前缀吗?

如果没有,那么hashmap怎么样?拿一把很大的钥匙,把它缩小到很小的尺寸,用它作为结构的索引。

答案 1 :(得分:3)

特里?

如果你有两个几乎相同的长按键,Map会从头开始比较它们,但是trie只会比较之前比较尚未消除的后缀(如果你明白我的意思) 。因此,在这种情况下,特里会更节省时间。

尝试可以通过各种方式进行优化,您可能还需要查看三元树。

答案 2 :(得分:1)

这是一个:

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)

它实质上是在列表元素上创建一个前缀树,因此您只需根据需要进行比较。