在Haskell中显示矩阵的实例 [英] Show instance for matrix in Haskell

查看:98
本文介绍了在Haskell中显示矩阵的实例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直试图创建一个展示实例,以便可视化给定的矩阵,并创建一个包含矩阵之间和周围的列的轮廓。我到目前为止设法完成的工作如下:

$ p $ data $ a $ Mat $ [$ a $]
实例(显示a)=> Show(Mat a)
show(Mat x)=\\\
++--- \\\
++ unlines(map(\r - > showRow r ++\ n ---)x)++\\\

其中
showRow list =|++ unwords(map(\v-> show v ++|)列表)

假设我们有一个矩阵 Mat [[1,2,3 ],[4,5,6]] ,我们想测试。



命令行的输出如下:

  --- 
| 1 | 2 | 3 |
---
| 4 | 5 | 6 |
---

我想要实现的格式给定的矩阵在每列的其余部分上方有水平线,如下所示:

  --- --- --- 
| 1 | 2 | 3 |
--- --- ---
| 4 | 5 | 6 |
--- --- ---


解决方案

如果假设矩阵的所有行都相同列数(或至少表示第一行) y矩阵的列数至少与其他列数一样多),并且这三个破折号可以作为任何单元格的边界,您可以通过取长度来计算行间使用的破折号数量

如果这些假设不成立,您需要对数组进行一次遍历来计算任何行的最大宽度,然后第二遍来绘制矩阵。如果矩阵可以包含 [0..9] 范围之外的数字,则还需要计算每列的宽度。



算法可能是:
$ b


  1. 将矩阵中的每个数字映射到 String ,生成一个 [[String]]

  2. 生成列宽度列表,其元素为最大宽度

  3. 左键填充 [[String]] 中的每个字符串,其列宽为空格。

  4. 连接每一行的列,在元素和适当的左右边界之间添加适当的分隔符。结果是一个 [String] ,其元素是每一行的图形表示形式。

  5. 如果您希望在上面添加水平线,下面或行之间,获取 [String] 中任何元素的长度(因为所有列现在被填充到其最大宽度,所有行现在应该具有相同的长度)并生成这些数字的绘图字符,如ASCII ---或Unicode ┌─┬─┐

  6. 将行和分隔符行连接成由换行符分隔的 String 。 b $ b

正如Rein Henrichs在评论中提到的那样,您可能会考虑将此函数命名为 show 以外的其他名称。

I've been trying to create a show instance in order to visualize a given matrix and also, to create an outline with columns around and in between the matrix. What I managed to accomplish so far is the following:

data Mat a = Mat [[a]]
instance (Show a) => Show (Mat a) where
show (Mat x) = "\n" ++ " ---\n"++unlines ( map (\r -> showRow r ++ "\n ---") x ) ++ "\n"
    where
      showRow list = "¦ "++unwords ( map (\v -> show v ++" ¦") list)

Assuming we have a matrix Mat [[1,2,3],[4,5,6]] that we would like to test.

The output from the command line is the following:

 ---
¦ 1 ¦ 2 ¦ 3 ¦
 ---
¦ 4 ¦ 5 ¦ 6 ¦
 ---

What I would like to achieve is to format the given matrix with horizontal lines above the rest of each column, like that:

 --- --- ---
¦ 1 ¦ 2 ¦ 3 ¦
 --- --- ---
¦ 4 ¦ 5 ¦ 6 ¦
 --- --- ---

解决方案

If you make the assumptions that all rows of a matrix have the same number of columns (or at least that the first row of any matrix has at least as many columns as any other), and that three dashes suffice as the border for any cell, you can calculate the number of dashes to use between rows by taking the length of the leading row.

If these assumptions do not hold, you need to make one pass over the array to calculate the maximum width of any row, then a second pass to draw the matrix. If matrices can contain numbers outside the range [0..9], you would also need to calculate the width of each column.

The algorithm might be:

  1. Map each number in the matrix to a String, generating a [[String]].
  2. Generate a list of column widths, whose elements are the maximum width of any row’s element in that column.
  3. Left-pad every string in the [[String]] with spaces to its column width.
  4. Concatenate the columns of each row, adding the appropriate separator between elements and the appropriate left and right borders. The result is a [String] whose elements are the graphical representation of each row.
  5. If you wish to add horizontal rules above, below, or between the rows, take the length of any element of the [String] (As all columns are now padded to their maximum width, all rows should now have the same length.) and generate that number of box-drawing characters, such as ASCII "---" or Unicode "┌─┬─┐".
  6. Concatenate the rows and the separator lines into a String separated by newlines.

As Rein Henrichs mentioned in a comment, you might consider naming this function something other than show.

这篇关于在Haskell中显示矩阵的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆