Print Array2 2D char数组

时间:2018-04-18 19:52:17

标签: arrays functional-programming sml smlnj ml

我正在尝试在SML中打印一个2D char数组,其格式为:

val arr = Array2.fromList [[#"a", #"b", #"c"], [#"d", #"e", #"f"], [#"g", #"h", #"i"]];

请注意,每行中的最后一个元素不是 #"\n"元素。

结果必须采用以下形式,其中每一行都以新行表示:

abc
def
ghi

有没有办法在SML中执行此操作?

2 个答案:

答案 0 :(得分:1)

您可以按如下方式编写函数:

fun print_arr (arr,N,col) = ()
| print_arr(arr,row,M) = (print("\n");print_arr(arr,row+1,0))
| print_arr(arr,row,col) = (print(Array.sub(arr,row,col)); print_arr(arr,row,col+1))

请注意,N,M分别是行数和列数。在这里,您可以递归地打印每个元素。到达行尾时,打印一个新行,然后调用该函数,并将下一行作为参数。您的初始参数应为(arr, 0 0 )。

答案 1 :(得分:1)

您可以使用Array2.row, Array2.nRowsCharVector.tabulate一次迭代并打印整行:

Array2.row   : 'a array * int -> 'a Vector.vector
Array2.nRows : 'a array -> int
CharVector.tabulate : int * (int -> char) -> string

您可以定义一个函数app_row,它接受​​Array2.array并在每一行上调用一个函数f,并将其作为向量提取。一个函数vec_to_str,它接收该向量vec并将其转换为字符串;然后打印出来。

fun app_row f arr =
    let fun loop i = if i = Array2.nRows arr then ()
                     else (f (Array2.row (arr, i)); loop (i+1))
    in loop 0 end

fun vec_to_str vec =
    CharVector.tabulate (Vector.length vec, fn i => Vector.sub (vec, i))

fun showMatrix arr =
    app_row (fn row => print (vec_to_str row ^ "\n")) arr

尝试这个尺寸:

- showMatrix arr;
abc
def
ghi
> val it = () : unit

此解决方案的I / O密集程度应低于使用Array2.appi并一次打印一个字母。它也稍微复杂一些,因为它涉及将“ char Vector.vector ”转换为“ CharVector.vector ”(又名 string )。 (两者之间的区别很微妙。)

仍然是一种类似于P. Antoniadis解决方案的替代解决方案,但您不需要指定维度(因为它们可以使用例如Array2.nColsArray2.nRows提取):< / p>

fun showMatrix arr =
    Array2.appi Array2.RowMajor (fn (_, col, c) =>
      print (str c ^ (if col + 1 = Array2.nCols arr then "\n" else "" )))
      {base=arr,row=0,col=0,nrows=NONE,ncols=NONE}