Haskell实现类15 Puzzle的puzz函数时如何复用中间结果迭代多步移动
解决方法
你需要先把单步移动的逻辑抽成独立函数,再通过折叠操作迭代应用所有移动步骤。Haskell不需要显式声明可变变量保存中间结果,折叠操作会自动传递每一步的输出作为下一步的输入。
首先补全代码里缺失的类型定义,你用到的Result本质是字符串列表:
type Result = [String]
然后把你写的单步移动逻辑抽成独立的step函数,接收当前棋盘和单个移动字符,返回移动后的新棋盘:
step :: Result -> Char -> Result step currentBoard moveChar = [ change r | r <- currentBoard ] where change row = [ if c == ' ' then moveChar else if c == moveChar then ' ' else c | c <- row ]
最后puzz函数直接用foldl迭代所有移动步骤即可。foldl会从初始棋盘开始,依次把移动序列里的每一个字符传入step函数,用上一步的输出作为下一步的输入,自动完成所有轮次的移动:
puzz :: Result -> [Char] -> Result puzz initBoard moves = foldl step initBoard moves
如果你的需求要求最终把空白格替换为_,可以在最后加一步转换:
puzz initBoard moves = map (map (\c -> if c == ' ' then '_' else c)) $ foldl step initBoard moves
你可以直接用给出的测试用例验证:
s1 = ["AC DE", "FBHIJ", "KGLNO", "PQMRS", "UVWXT"] p1 = "CBGLMRST" -- 调用测试 main = print $ puzz s1 p1
输出会匹配你给出的预期结果。
内容的提问来源于stack exchange,提问作者Duhab
相关产品推荐
相关产品推荐

