输出一个元素我想要的次数 [英] Output an element the number of times I want
问题描述
我有此代码:
lado :: [([Char],Int)] -> [[Char]]
lado xs = [a | (a,b) <- xs]
我需要输出:
> lado [("A",3),("B",2),("C",1)]
["A","B","C","A","B","A"]
我必须输出"A" 3次,然后是"B" 2倍于"C". 1次,但我只能通过此代码获得此["A","B","C"].
I have to output "A" 3 times, then "B" 2 times then "C" 1 time but I only get this ["A","B","C"] with this code.
推荐答案
您已经在尝试使用列表推导.多使用它们.
You already use list comprehensions in your attempt. Use them some more.
lado :: [([Char],Int)] -> [[Char]]
lado xs = [a | (a,b) <- xs, b <- [1..b]]
测试:
> lado [("A",3),("B",2),("C",1)]
["A","A","A","B","B","C"]
正如你的问题所说,
我必须输出"A" 3次,然后是"B" 2倍,然后"C"为0. 1次
I have to output "A" 3 times, then "B" 2 times then "C" 1 time
但是如果您确实想要["A","B","C","A","B","A"]
,那么
But if it is really ["A","B","C","A","B","A"]
you want, then
lado :: [(a,Int)] -> [a]
lado [] = []
lado ((a,1):b) = a : lado b
lado ((a,n):b) = a : lado (b ++ [(a,n-1))])
,可以用Data.List
中的unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
进行编码,
which can be coded with unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
from Data.List
,
lado :: [(a,Int)] -> [a]
lado xs = unfoldr g $ xs
where
g [] = Nothing
g ((a,1):b) = Just (a, b)
g ((a,n):b) = Just (a, b ++ [(a,n-1)])
可以用Prelude的iterate :: (a -> a) -> a -> [a]
等模仿,例如
which can be emulated with Prelude's iterate :: (a -> a) -> a -> [a]
etc., as
lado :: [(a,Int)] -> [a]
lado xs = map (fst . head) . takeWhile ( ... ) . iterate g $ xs
where
g [] = []
g ((a, ... ):b) = b
g ((a, n ):b) = b ++ [(a, ... )]
测试:
> lado [("A",3),("B",2),("C",1)]
["A","B","C","A","B","A"]
填写空白...
以使其起作用.
Fill in the blanks ...
to make it work.
如 @dfeuer 所述,列表末尾重复出现的单例会损害整体效率.非常感谢他的投入和讨论,包括此处的两个答案和评论,甚至还有github 要点,这可以通过通常的FP范式(更不用说把戏")来反向建立列表来弥补,例如
as @dfeuer notes, the repeated singleton-appending at list's end is detrimental to overall efficiency. With big thanks to his input and discussion, including the two answers and comments here and even a github gist, this can be remedied by the usual FP paradigm (not to say "trick") of building a list in reverse, as
lado :: [(a,Int)] -> [a]
lado xs = go (filter ((> 0) . snd) xs) []
where
go [] [] = []
go [] r = go (reverse r) []
go ((a,1):b) r = a : go b r
go ((a,n):b) r = a : go b ((a,n-1):r)
在所有输出中使用reverse
成本摊销,这只会为每个输出项增加恒定的开销.
With the reverse
cost amortized over all the output this will add only a constant overhead per each output item.
这篇关于输出一个元素我想要的次数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!