如何在Haskell中实现将列表元素插入玫瑰树各叶子节点的append函数
问题解答
你现有代码的核心问题是没有跟踪列表元素的消耗进度,每次处理叶子节点都只取列表第一个元素,也没有把剩余列表传递给后续叶子的处理逻辑,所以所有叶子都会用同一个元素。
我们可以通过带状态的辅助函数解决这个问题:辅助函数除了返回处理后的玫瑰树,还会返回当前剩余未使用的元素列表,保证元素按顺序分配给前序遍历到的叶子节点。
实现代码
-- 玫瑰树定义 data R = B [R] deriving (Show, Eq) -- 加Show和Eq方便测试验证 -- 辅助函数:输入原始树、待分配列表,返回(处理后的树, 剩余未使用列表) appendHelper :: R -> [R] -> (R, [R]) -- 遇到叶子节点,用列表第一个元素替换,返回剩余列表 appendHelper (B []) (l:rest) = (l, rest) -- 遇到分支节点,依次处理所有子节点,逐个消耗列表元素 appendHelper (B children) list = (B processedChildren, finalRest) where -- 批量处理子节点的辅助逻辑 processAll [] currentRest = ([], currentRest) processAll (child:others) currentList = let (processedChild, restAfterChild) = appendHelper child currentList (processedOthers, restAfterAll) = processAll others restAfterChild in (processedChild : processedOthers, restAfterAll) (processedChildren, finalRest) = processAll children list -- 对外暴露的append函数,直接取处理后的树即可(题目保证列表长度和叶子数一致,不会有剩余元素) append :: R -> [R] -> R append origin list = fst $ appendHelper origin list
验证示例
你给出的测试用例运行结果完全符合预期:
输入:
origin = B [B [B [], B []], B [], B []] addList = [ B [B [], B []], B [], B [B []], B [] ] append origin addList
输出:
B [B [B [B [B [], B []]], B [B []]], B [B [B []]], B [B []]]
内容的提问来源于stack exchange,提问作者paco neitor
相关产品推荐
相关产品推荐

