2d矩阵sml插入列表 - 简单的代码

时间:2017-01-14 21:41:30

标签: list recursion multidimensional-array smlnj ml

我有一个sml-nj项目,我想在其中使用列表列表'结构,有" Squares"。我试图递归地将值插入列表列表,但我仍然不知道如何将元素插入到2d列表中。 注意 - 我只能使用' REF',http://smlfamily.org/Basis/list.html#SIG:LIST.app:VAL这些功能。

datatype SquareContent = Mine | Digit of int | Blank;
datatype Square = Revealed of SquareContent | Concealed of SquareContent;
fun createMineSweeperGrid (n:int)
:(Square list   list)= 
let
fun createMines (rowCounter:int, colCounter:int
, retGame:Square list list):(Square list list) = 
if rowCounter=n then   
retGame         (* finished all rows, should be n lists of size n*)
else
if colCounter=n then   (*finished current row, move on*)
createMines (rowCounter+1, 0, mines,retGame)
else   

let
val squareToInsert = Concealed(Mine)  (* I wish to insert 'squareToInsert'         
to retGame[rowCounter][colCounter], it's done dynamically, but I don't know 
how to do that *)
in
createMines (rowCounter, colCounter+1, retGame) 
end

in
createMines (0,0,[])
end

我可以插入任何类型的Square,它是动态决定的,在这里我只举例说明隐藏的Mine,所以你可以帮助我..帮助..?

1 个答案:

答案 0 :(得分:2)

要认识到的重要一点是,在标准ML中,您不会改变现有结构;相反,你创造了新的。 (标准ML通过ref和它的朋友来支持支持可变结构,但它不是轻易做的事情,我看到你已经 - 正确地 - 排除了它。)< / p>

因此,一般情况下,将某些内容插入链接列表的中间是非常昂贵的:它需要将列表“展开”到您要插入的位置,然后插入值,最后构建所有内容的副本解开了。例如,这是一个在列表的索引x处插入值i的函数:

fun insert (x, 0, L) = x :: L
  | insert (x, i, h :: t) = h :: insert (x, i - 1, t)
  | insert (_, _, nil) = raise Subscript

幸运的是,编写了您的函数,以便不必在已构建的链表的中间插入任何内容;相反,如果我正确理解它正在尝试做什么,它总是将新方块放在第一个列表的开头。所以:

let
  val squareToInsert = Concealed(Mine)
  val topRow :: rest = retGame
in
  createMines (rowCounter, colCounter+1, (squareToInsert::topRow)::rest) 
end

请注意,您还需要修复另一个错误,即您实际上从未创建过新行:您有关于“已完成当前行,继续前进”的评论,但之后它只是完全相同,就像它一样仍然在同一行(只是重置数字,好像它已移动到一个新行)。要解决此问题,请在要在顶部添加新行时使用[] :: retGame,并使用[[]]代替[]作为初始板(以便以空行开头) )。