【发布时间】:2020-08-05 08:54:06
【问题描述】:
函数必须是这样的:insertElemAt :: a -> [Int] -> [a] -> [a]。
例子:
insertElemAt 0 [2,5,9] [1..10]
= [1, 0, 2, 3, 0, 4, 5, 6, 0, 7, 8, 9, 10]
insertElemAt 0 [1,2,4,8] [0,1,0,0,1,1,0,1]
= [0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1]
我只知道初学者 Haskell(if 与管道 | 和递归),但我尽我最大的努力解决这个问题,但它从来没有奏效。这是我最近的尝试:
insertElemAt x [0] ys = ys
insertElemAt x [1,2] ys = x:x:ys
insertElemAt x [] ys = ys
insertElemAt x xs [] = []
insertElemAt x (n:ns) (y:ys) = y:insertElemAt x (n-1:ns) ys
我也尝试过类似的方法,但这似乎很混乱,我认为第一个更好:
insertElemAt :: a -> [Int] -> [a]-> [a]
insertElemAt x [0] ys = ys
insertElemAt x [1,2] ys = x:x:ys
insertElemAt x (n:ns) (y:ys) = y:insertElemAt x (map reduc (n:ns)) ys
reduc (n:ns) = n-1 : reduc ns
也许我的模式不好?我尝试了很多方式来编写它们。
我还必须能够使用这个函数并在一个名为insertElemsAt (:: [(a, Int)] -> [a] -> [a]) 的函数中使用它,它必须是上述函数的“通用”版本。所以我必须能够给在哪个位置我想插入什么样的元素。
因为我不能做第一个,所以我对这个更迷茫。这是示例。我不知道如何使用管道if-s 和递归来做到这一点:
insertElemsAt (zip [0,1,1] [2,5,9]) [1..10]
= [1, 0, 2, 3, 1, 4, 5, 6, 1, 7, 8, 9, 10]
insertElemsAt (zip [0,1,1,1] [1,2,4,8]) [0,1,0,0,1,1,0,1]
= [0, 1, 0, 1, 1, 0, 0, 1, 1, 1, 0, 1]
谁能以最简单的方式向我解释如何做到这一点?提前感谢您的帮助!
【问题讨论】:
-
我认为你最好使用一个累加器来跟踪当前索引。此外,您应该始终查看要插入的索引列表的头部。像
insertElementAt x [1,2]这样的模式很可能“太具体”。这里。我认为您的第一个模式insertElemAt x [0]在语义上也是不正确的,因为这里的结果应该是x:ys。 -
这里一个不言而喻的前提是索引列表是排序的
标签: list haskell recursion insert guard-clause