2011-04-11 79 views
2

嗨 Im新的Haskell,并希望编写一个简单的代码。 我想写一个函数来创建一个数字列表。 在那里它与1开始的,并用2N增加+ 1个N + 1 所以例如输出应该像 取6 myList中= [1,3,4,7,9,10]Haskell创建号码列表

我想我需要使用递归,但不知道如何以列表格式执行 。

任何帮助将不胜感激。谢谢

+1

您的示例将所有输出排序,这会创建奇数交错模式。你是否需要对它们进行排序(无限 - 就是说,如果你只想要有限的许多,你可以随时排序)?关于重复的东西呢?即如果某个数字可以写成2n + 1和3m + 1,其中n和m是列表的元素,它应该出现两次吗? – luqui 2011-04-11 05:18:13

回答

6

其实,我不知道我是否有你的想法。 但这是你想要的吗?

generator list = list ++ generator next 
    where 
    next = (map (\n -> 2 * n + 1) list) ++ (map (\n -> 3 * n + 1) list) 

哦,你可以用generator [1]来启动。像这样:

take 100 $ generator [1] 
+0

+1哇,优雅的解决方案。我正在寻找优先级队列和东西。 – luqui 2011-04-11 05:24:49

+0

这是有点欺骗性,因为它是“更多排序”,但仍未排序或结尾。 – 2011-04-11 14:33:53

1
merge xs [] = xs 
merge [] ys = ys 
merge (x:xs) (y:ys) | x == y = x : merge xs ys 
        | x < y = x : merge xs (y:ys) 
        | otherwise = y : merge (x:xs) ys 

print $ take 10 $ merge [1,3..] [1,4..] 
--[1,3,4,5,7,9,10,11,13,15] 
+0

这似乎是错的,他说前几项是[1,3,4,7,9,10]。但你的产品[1,3,4,5,7,9,10]。 – 2011-04-11 07:21:31

+0

但是5的形式是2n + 1,不是吗?或者我误解了这个问题? – Landei 2011-04-11 09:55:44

+0

我认为'n'必须是'2n + 1'列表的前面部分才是有效的。 – 2011-04-11 14:54:58

1

正如luqui说,我们可以使用信息,如做重复的事,并不会为了物质。如果答案是否定的,并没有那么简单concatMap正常工作:

myList = 1 : concatMap (\n -> 2*n+1 : 3*n+1 : []) myList 

结果:

> take 20 myList 
[1,3,4,7,10,9,13,15,22,21,31,19,28,27,40,31,46,45,67,43] 

如果答案是肯定的,是的话,我想这可能是更清洁,但是这已经足够:

myList = abs 
    where 
    abs = merge as bs 
    as = 1 : map (\n -> 2*n+1) abs 
    bs = 1 : map (\n -> 3*n+1) abs 
    merge (x:xs) (y:ys) 
     | x == y = x : merge xs ys 
     | x < y = x : merge xs (y:ys) 
     | otherwise = y : merge (x:xs) ys 

结果:

> take 20 myList 
[1,3,4,7,9,10,13,15,19,21,22,27,28,31,39,40,43,45,46,55]