删除字符串中的每个第n个元素
问题描述:
如何删除字符串的每个第n个元素?删除字符串中的每个第n个元素
我猜你会以某种方式使用drop
函数。
像这样滴第一个n,你怎么能改变这个,所以只有第n个,然后是第n个,等等,而不是所有的?
dropthem n xs = drop n xs
答
remove_every_nth :: Int -> [a] -> [a]
remove_every_nth n = foldr step [] . zip [1..]
where step (i,x) acc = if (i `mod` n) == 0 then acc else x:acc
这里的功能是什么:
zip [1..]
用于索引的所有项目在列表中,因此如zip [1..] "foo"
变成[(1,'f'), (2,'o'), (3,'o')]
。
然后使用right fold处理索引列表,该索引列表累积索引不能被n
整除的每个元素。
这是一个稍微长一点的版本,它基本上做了同样的事情,但是避免了来自zip [1..]
的额外内存分配,并且不需要计算模量。
remove_every_nth :: Int -> [a] -> [a]
remove_every_nth = recur 1
where recur _ _ [] = []
recur i n (x:xs) = if i == n
then recur 1 n xs
else x:recur (i+1) n xs
答
尝试结合take
和drop
来实现此目的。
take 3 "hello world" = "hel"
drop 4 "hello world" = "o world"
答
-- groups is a pretty useful function on its own!
groups :: Int -> [a] -> [[a]]
groups n = map (take n) . takeWhile (not . null) . iterate (drop n)
removeEveryNth :: Int -> [a] -> [a]
removeEveryNth n = concatMap (take (n-1)) . groups n
答
简单。取(n-1)个元素,然后跳过1,冲洗并重复。
dropEvery _ [] = []
dropEvery n xs = take (n-1) xs ++ dropEvery n (drop n xs)
或者在节目样式效率的缘故
dropEvery n xs = dropEvery' n xs $ []
where dropEvery' n [] = id
dropEvery' n xs = (take (n-1) xs ++) . dropEvery n (drop n xs)
答
我喜欢以下解决方案:
del_every_nth :: Int -> [a] -> [a]
del_every_nth n = concat . map init . group n
你只需要定义一个函数group
哪些群体在长的部分名单ñ。但是,这是很容易的:
group :: Int -> [a] -> [[a]]
group n [] = []
group n xs = take n xs : group n (drop n xs)
+0
hlint will suggest使用'concatMap'而不是'concat。 map' – 2011-03-15 22:46:30
而不是'zip'和'mod'这是稍贵,为什么不使用'cycle' [ 1..n]并与1比较? – Peaker 2011-03-13 12:41:32
'remove_every_nth n = map snd。过滤器((/ = 0)。(\'mod \'n).fst)。 zip [1 ..]' – Alvivi 2011-03-13 12:48:20
@Peaker:谢谢你的建议。我不确定如何在不使用'zip'的情况下利用'cycle',但我以不同的方式提高了效率。 – shang 2011-03-13 12:48:37