5

我有以下 Int 列表:

t1 = [1000, 1001, 1002, 1003, 1004]
t2 = [2000, 2001, 2002]
t3 = [3000, 3001, 3002, 3003]

列表大小是可变的,它们不只是像这个例子中的 3。它们可以有 1 个或更多元素。然后我有这个:

tAll = [t1, t2, t3]

我需要一个将tAll变成这样的函数:

[[1, 1000, 2000, 3000],
[2, 1001, 2001, 3001],
[3, 1002, 2002, 3002],
[4, 1003, 0, 3003], 
[5, 1004, 0, 0]]

是否有捷径可寻?

编辑: 对不起,我匆忙发布了这个,这不是我想要的。我更新了上面的代码...

4

4 回答 4

9

如果您仍然感兴趣,这里有一个单线供您使用:

zipWith (:) [1..] $ take (maximum $ map length tAll) 
                         (transpose (map (++repeat 0) tAll))

编辑:好的,最好用两行写:)

于 2008-12-21T19:31:01.097 回答
2

好吧,这是 Haskell 初学者的编写方式,但由于它正在执行显式递归,因此可能有更好的方式。:-)

head0 [] = 0
head0 xs = head xs

tail0 [] = []
tail0 xs = tail xs

nreorder n ts
  | all null ts = []
  | otherwise   = (n : map head0 ts) : nreorder (n+1) (map tail0 ts)

nreorder 1 tAll打印您想要的列表。您可以通过执行以下操作来避免这些索引:

reorder ts
  | all null ts = []
  | otherwise   = (map head0 ts) : reorder (map tail0 ts)

所以reorder tAll = [[1000,2000,3000],[1001,2001,3001],[1002,2002,3002],[1003,0,3003],[1004,0,0]],和(稍微清理了感谢mattiast):

nreorder ts = zipWith (:) [1..] (reorder tAll)

以便nreorder tAll打印您想要的列表。

于 2008-12-18T20:38:12.637 回答
2

闻起来像作业,所以我不会给出代码,但有一些提示:
- 结果列表的长度都是相同的,这是列表的最大值。找到最大值并用零填充所有其他列表(使用惰性可以用无限的零列表填充所有列表)。
- 得到一个工作的中间版本,它只打印你最终答案的第一列......
- 当你有这个工作时,得到第二列......剩下的应该是肉汁。

编辑:评论表明这不是家庭作业,所以:

列表 = [[1000, 1001, 1002, 1003, 1004],[2000, 2001, 2002],[3000, 3001, 3002, 3003]]

main = do mapM_ (putStrLn.show) (旋转列表) 旋转列表 = [(i+1):map (!!i) 填充列表 | i<-[0..(len-1)] ] 其中 len = 最大 $ 地图长度列表 paddedlist = map (++repeat 0) 列表

于 2008-12-18T20:39:37.563 回答
1

zip3会将 3 个列表变成一个三元组列表。如果你想要长度为三的列表,你可以使用zipWith3 (\a b c -> [a,b,c])

如果你想要一些不同的细节(如更新的请求),你必须自己动手。我想说,把你的终止条件放在第一位,然后处理一般情况。您应该有两个辅助函数——一个以您想要的方式修复值(例如,“head_or_zero”),另一个用于处理已终止的输入列表(例如,“tail_or_nil”):


fix _ [] [] [] = []
fix i as bs cs = [i, hoz as, hoz bs, hoz cs]:fix (i+1) (ton as) (ton bs) (ton cs) where
    hoz [] = 0
    hoz x:xs = x
    ton [] = []
    ton x:xs = xs
于 2008-12-18T19:59:03.150 回答