Haskell实现列表按输入数值旋转时如何处理负输入参数
你当前的实现仅支持非负数值的旋转逻辑,要适配负整数输入,核心逻辑是先将旋转量对列表长度取模,转换为等效的非负偏移值:列表旋转次数等于自身长度时等价于不旋转,负向旋转k次等价于正向旋转列表长度 - k % 长度次,Haskell的mod运算天然支持这个转换,无需额外做符号判断。
修改后的代码(复用原有逻辑)
-- rotate : 接收一个列表与旋转量,按指定元素个数对列表执行旋转 rotate :: [a] -> Int -> [a] rotate [] _ = [] -- 空列表直接返回,避免求长度报错 rotate ls m = rotatePositive ls (m `mod` length ls) where -- 原有正旋转逻辑复用 rotatePositive xs 0 = xs rotatePositive (x:xs) n = rotatePositive (xs ++ [x]) (n-1)
功能验证
-- 正向旋转测试 rotate [1,2,3,4] 2 -- 输出 [3,4,1,2] -- 负向旋转测试 rotate [1,2,3,4] (-1) -- 输出 [4,1,2,3] -- 超长度旋转量测试,自动取模等效值 rotate [1,2,3,4] 5 -- 等价旋转1次,输出 [2,3,4,1]
更高效的优化实现
原有实现每次执行xs ++ [x]的时间复杂度为O(n),整体旋转效率是O(n²),可以用splitAt相关逻辑优化到O(n):
rotate :: [a] -> Int -> [a] rotate [] _ = [] rotate ls m = let len = length ls offset = m `mod` len in drop offset ls ++ take offset ls
内容的提问来源于stack exchange,提问作者Rain
相关产品推荐
相关产品推荐

