在 haskell -> TRIE 中使用自定义递归数据类型
Posted
技术标签:
【中文标题】在 haskell -> TRIE 中使用自定义递归数据类型【英文标题】:Using custom recursive data type in haskell -> TRIE 【发布时间】:2021-12-28 06:23:13 【问题描述】:我正在学习 Haskell,但遇到了一个似乎很难的问题。
我有 Trie 的自定义递归数据类型。
data Trie keytype valuetype = TNode (Maybe valuetype) [Edge keytype valuetype]
deriving (Show, Eq)
type Edge e a = (e, Trie e a)
我正在尝试实现与它一起使用的功能。我发现如何遍历它不正确的顺序。
isTrieValid :: Ord e => Trie e a -> [e]
isTrieValid (TNode _ []) = []
isTrieValid (TNode _ ((edge, TNode maybe innerlist):children)) = edge : printChildren innerlist ++ printChildren children
where
printChildren :: Ord e => [Edge e valuetype] -> [e]
printChildren [] = []
printChildren ((edge_name, TNode _ innerlist):xs) =edge_name : printChildren innerlist ++ printChildren xs
例如。对于以下特里,返回所有“键”(边缘名称)->“abbce”
trie1 = TNode (Just 42) [('a', TNode (Just 16) []),
('b', TNode Nothing
[('b', TNode (Just 1) []),
('c', TNode (Just 5) []),
('e', TNode (Just 2) [])
])
]
现在我正在尝试创建基于“键”查找元素的函数,如下所示:
trieLookup :: Ord e => [e] -> Trie e a -> Maybe a
但我看到了两个问题。首先,如果我用递归遍历 Trie,我不确定如何处理第一个元素。因为第一个元素没有“键”,我应该返回什么?我认为空字符串会起作用,但我希望将整个“Ord”类型类用于键,这样会引发类型错误。
我尝试创建的下一个函数将检查 Trie 有效性。
isTrieValid :: Ord e => Trie e a -> Bool
我的理解是,Trie 必须具备这种品质才能被认为是有效的。
当前元素之后的所有元素都按第一个元素排序(按Ord e排序) 没有两个后继者拥有相同的密钥因此,如果根节点有效并且所有子树/subtriee(不确定如何编写)也有效,则整个 TRIE 有效。
我想创建一个函数来检查一个节点的有效性,然后使用上面的函数在所有节点上复制它,但我失败了。
感谢您的帮助。
【问题讨论】:
Mod note:不要仅仅因为它是一个积极的家庭作业而标记这个问题。 We allow homework questions,只要他们是properly asked,,这个问题似乎是(至少对我来说是一个非中小企业)。这是一个家庭作业问题不是一个密切的原因。我们还don't care if it's part of anything active或违反荣誉守则。 也就是说,如果这被证明是由于其他原因而可以关闭的,请继续使用适当的标志来标记相关原因,但它是一个积极的家庭作业不是这样的原因。 Abdul,请随意忽略这些 cmets。您在这里没有做错任何事情,这些 cmets 不是为了解决您的行为 明确地说,“没有做错任何事”有点过于宽泛——我们不能肯定地说。 Abdul 没有违反 Stack Overflow 规则或政策,但根据学校政策,他可能仍然做错了什么。如前所述,Stack Overflow 无法强制执行这些,因此问题确实是这里的主题,但在更广泛的意义上它可能仍然是“错误的”。 【参考方案1】:我建议更改您的 Trie 类型。 isTreeValid
的所有属性都可以通过使用Data.Map k v
而不是[Edge k v]
轻松维护。
我真的不明白你在用trieLookup
谈论什么问题。看起来很简单,如果输入键 ([e]
) 为空,则返回根处的值,否则进一步下降到树中。什么时候会出现如何治疗根的问题?如果您需要有关该功能的帮助,请附上您解决该问题的尝试并描述问题所在或需要改进的地方。
【讨论】:
我很想改变它,但我不能。这就是任务。 (我在高中) trieLookup 的问题在于,为了有效地做到这一点,我必须检查钥匙,这样我就不会去那些不可能是我正在寻找的价值的分支。所以对于 TRIE,我上面的键“bb”应该返回 1。所以我需要将 b 与 a 和 b 进行比较,发现 a 是 something 并忽略整个分支。我来自python,所以haskell与众不同......如果问题看起来微不足道,我很抱歉。我只是没有看到它。我可以比较字符串,但是当我在控制台中尝试它时,它并没有做我需要做的事情。以上是关于在 haskell -> TRIE 中使用自定义递归数据类型的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Haskell 中访问没有记录语法的自定义数据类型的字段?