1

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 関数のケースが原因であることがわかりますが、修正方法がわかりません。また、文字は、それらの前に印刷されたものを考慮しません。これを修正する方法についての助けをいただければ幸いです。

4

2 に答える 2

3

少し前に、タブ区切りのテーブル(CSVスタイル)を取得してコンソールにきれいに印刷する小さなスクリプトを作成しました。関連する部分を抽出し、ここにソースコードをアップロードしました。たとえば、あなたの入力が与えられた

m = [[1,23,456],[78,-90,123],[4567,8,9]]

putStrLn $ showMat mになります

  1  -500 -4
100 15043  6
  5     3 10

左揃えにしたい場合は、一番下に機能(コメントアウト)もあります。

于 2012-10-27T18:43:04.650 に答える
1

行ごとに新たに計算showMatしますrowmaxselements特に、行列に残っている各行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各行の数値の最大長を計算 (試行) しますが、実際には各列の数値の最大長が必要です。その結果の 1 つは、時々負の数を に渡すこと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

于 2012-10-27T17:20:42.843 に答える