我正在写一个非常简单的复制函数,它接受一个数字列表并返回一个列表,每个数字都是重复的。接受值和元素的复制函数对我来说更简单,因为它不需要保存状态。
但是在Haskell,我到目前为止得到了这个:
> replicate' [] = []
> replicate' (x:xs)
> | x == 1 = x: replicate' xs
> | otherwise = x: replicate'(x-1:xs)
这显然是错误的,因为对于replicate' [2,2]
,它会打印[2,1,2,1]
而不是[2,2,2,2]
我知道我必须将x保存到其他变量并递减它但我不相信我知道它的语法。
哎呀,人们对这个问题感到有些困惑。例如,来电replicate' [2,3,1]
应该返回[2,2,3,3,3,1]
,而不只是[2,2,3,3,1,1]
,就像我认为你们在想的那样
答案 0 :(得分:5)
不,你不是。这句话表明你有一些误解。我建议你考虑为什么你认为这是真的,并解决这个问题。我知道我必须将x保存到其他变量
中
至于你的问题,你有一个良好的开端,向你展示递归,基本情况和基本语法。干得好。您提供的代码是:
replicate' [] = []
replicate' (x:xs)
| x == 1 = x: replicate' xs
| otherwise = x: replicate'(x-1:xs)
基本情况很好,但为什么要从x中减去一个呢?为什么它(再次)出现在复制调用中?只要想想你想要的操作,就不需要对元素进行任何算术 - 你想构建一个重复每个元素的列表,语法就像newelement : rest
- 我们可以将:
读作& #34;缺点&#34 ;.所以你的第二个案例应该是:
replicate' (x:xs) = x : x : replicate' xs
再次编辑,因为您已经澄清了元素是指示它们必须出现多少次的数字。好吧,显而易见的解决方案是使用replicate(from base)作为replicate'
的一部分:
replicate' [] = []
replicate' (x:xs) = replicate x x ++ replicate' xs
在上面我们复制每个元素的次数等于元素的值,然后通过++
将该列表连接到递归调用。更简单的版本是:
replicate' = concatMap (\x -> replicate x x)
例如:
Prelude> concatMap (\x -> replicate x x) [1..3]
[1,2,2,3,3,3]
答案 1 :(得分:3)
replicate' [] = []
replicate' (x:xs) = x:x:replicate' xs
您可以立即添加两个项目。
*Main> replicate' [1,2,3]
[1,1,2,2,3,3]
<强> UPD:强>
duplicate::Int->Int->[Int]
duplicate 0 x = []
duplicate n x = x:duplicate (n-1) x
replicate' [] = []
replicate' (x:xs) = duplicate x x ++(replicate' xs)
答案 2 :(得分:1)
根据你的逻辑(但是很差的例子)我猜你想要重复每个元素的次数([2,3] -> [2,2,3,3,3]
)。
您可以将repeat'
函数编写为repeat' n = take n $ repeat n
并在复制函数中使用
replicate' :: [Int] -> [Int]
replicate' [] = []
replicate' (x:xs) = repeat' x ++ replicate' xs
更新:
你可以写一个重复的&#39;递归函数,你需要使用辅助函数来携带额外的计数信息。这样的事情应该有效
rep :: Int -> [Int]
rep x = rep' x x
where rep' x 0 = []
rep' x n = x: rep' x (n-1)
此处不是保存您作为递减参数传递的状态(计数),而是类似于循环计数。