[英]Printing a matrix with Haskell
我需要在haskell中打印出一个矩阵,所以它看起来像这样:
main> putStr (showMat [[1,-500,-4], [100,15043,6], [5,3,10]])
1 -500 -4
100 15043 6
5 3 10
到目前为止,我已经想出了这个:
type Matrix a = [[a]]
type IntMat = Matrix Integer
showMat :: IntMat -> String
showMat [] = ""
showMat ((y:ys):xs) = (printRow (rowmaxs) (elements) (y:ys)) ++ "\n" ++ showMat xs
where rowmaxs = rowMaxs ((y:ys):xs) ; elements = elementLengths (y:ys)
rowMaxs :: IntMat -> [Int]
rowMaxs [] = []
rowMaxs (x:xs) = [length (show (maximum (x)))] ++ (rowMaxs xs)
elementLengths :: [Integer] -> [Int]
elementLengths [] = []
elementLengths (y:ys) = [length (show y)] ++ (elementLengths ys)
printRow :: [Int] -> [Int] -> [Integer] -> String
printRow [] (a:as) (y:ys) = ""
printRow (z:zs) (a:as) [] = ""
printRow [] [] (y:ys) = ""
printRow [] [] [] = ""
printRow (z:zs) (a:as) (y:ys) = addSpaces (z-a) ++ show y ++ [' '] ++ printRow zs as ys
addSpaces :: Int -> String
addSpaces 0 = ""
addSpaces n = " " ++ addSpaces (n-1)
哪个返回:
Main> putStr (showMat [[1,23,1],[23,56,789],[1234,0,1]])
1 23 1
23 56
1234
我可以看到行末的元素丢失是由于printRow函数中的情况,但我不知道如何解决它。 字符也没有考虑到它们之前印刷的字符。 任何有关我如何解决这个问题的帮助将不胜感激。
我前段时间写了一个小脚本,它采用了一个以制表符分隔的表格(CSV样式)并将其打印到控制台上。 我已经提取了相关部分并在此处上传了源代码。 例如,给出您的输入
m = [[1,23,456],[78,-90,123],[4567,8,9]]
putStrLn $ showMat m
将使它成为
1 -500 -4
100 15043 6
5 3 10
如果你想要左对齐,最底层还有一个功能(注释掉)。
在showMat
您可以为每一行重新计算rowmaxs
和elements
。 特别是, rowmaxs
有一个元素用于矩阵中剩下的每一行 ,但printRow
使用它作为矩阵每列的含义。
编辑:这是一个稍微好一点的showMat
版本:
showMat :: IntMat -> String
showMat rows = concat (map perRow rows)
where rowmaxs = rowMaxs rows
perRow cols = printRow rowmaxs elements cols ++ "\n"
where elements = elementLengths cols
它仍然是错误的 - rowMaxs
(尝试)计算每行中数字的最大长度,但你真的想要每列中数字的最大长度。 这样做的一个结果是你偶尔会将负数传递给addSpaces
,因为这个版本的addSpaces
表现得非常优雅,所以这里的版本更加优雅:
addSpaces :: Int -> String
addSpaces n = replicate n ' '
所以现在我们得到这个:
*Main> putStr (showMat [[1,23,1],[23,56,789],[1234,0,1]])
1 23 1
23 56 789
1234 0 1
更好,但还没有正常工作。
我没有修复你代码中的所有错误,因为我觉得你还在学习,需要自己找到它们的经验。
我建议使用map
/ zipWith
/ zipWith3
而不是显式编写递归,因为它使代码更容易理解。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.