2013-04-09 42 views
1

所以我有一个类在Smalltalk中创建LazyMatrix。该类只有1个实例变量,不能是除Object之外的任何其他类的子类。 LazyMatrix的实例变量被称为block,并且必须是back。我初始化LazyMatrix这样的:懒惰列表S表达式矩阵的小问题

initialize 
block:=[nil] 

将会有一个方法,用于设置值

setRow:column:value: 

此方法将通过设置新的块为[#(IJ值)重新定义所述块[零]。 ]。随后的每一次调用都会向该块添加一个3的数组,因此它像[#(i j value)。[#(i j value)。[nil]]]一样展开,就像s表达式或“lazy list”一样。因此我需要访问该块的头部(即[#(i j value))以及该块的尾部(即[#(i j value)。[nil]])。我如何在smalltalk中做到这一点?我知道块上的调用值将返回尾巴...现在我需要返回头部。

回答

3

增加一个阵列到你的块没有得到你任何地方。根据行为而不是数据结构

我想你的老师确实给你提供了整体思路:给出一个行和一列,回答相关的值;否则请问“尾巴”的答案。

这就是从字面上如何使用块闭包(其中“尾部”是之前设置的块)在Smalltalk中实现它。在块内部,放置用于测试和回答以及尾递归的代码。不要制作数据结构,尾巴和头部只是这种编码风格的隐喻。

我刚在Squeak中实现了你的LazyMatrix,它只是几行代码。可爱的例子的确如此。根本不涉及数组或集合。

提示:这个难题的关键是意识到每次调用setRow:column:value:都可以创建一个新的块,它独立于所有先前创建的块。

+0

所以我将它初始化为'block:= [:i:j | 0]'。然后'setRow:column:value: | arr尾巴头| \t arr:= Array new:3。 \t arr at:1 put:i。 arr at:2 put:j。 arr at:3 put:val。 \t tail:= block。 \t head:= [:r:c | ARR。 \t \t((R =(改编于:1))和:(C =(ARR在:2))) \t \t ifTrue:[(ARR于:3)] \t \t ifFalse:[尾巴] \t \t]。 \t block:= head。' 这是一个好办法吗?你提到过不使用数组......我该如何做这样的事情?感谢您的帮助。 – 2013-04-10 22:04:33

+1

初始化是正确的。如果你问第一个块的任何行或列,它将回答为零。现在,假设你只有一个单独的块,它会回答例如如果行是3并且列5,则为42。对于任何其他行或列,它将改为评估第一个块。这很容易写下来,并将在一个地方模拟一个全零和一个单独的矩阵。现在,如果您创建第三个区块来回答例如69如果行是5,列是3,否则它评估第二个块,你将得到一个有2个非零值的矩阵。看到?没有阵列参与。 – 2013-04-11 07:17:50

+0

好的,我把它写成这样,一切似乎工作。还有一个问题......如果我想编写一些方法来将所有存储在矩阵中的值加上/乘以一些标量,那么最好的方法是什么?我应该使用某种形式的注射:?谢谢。 – 2013-04-11 11:21:23

0

我认为你可以在这里以两种方式去。第一个(我不推荐)将你的s表达式建模为lambda微积分中的列表。你基本上使用块作为功能,你就完成了。 Here你可以喜欢使用lambda微积分编写列表的解释。举个例子,在Smalltalk中你会写

empty = λfx.x 

empty := [:f :x | x]. 

现在,去这条道路将是一个面向对象的语言,我不会做基本上可以写一个函数式程序。如果你想对列表使用符号方法,那么你应该用对象来建模。拥有EmptyList类和Cons类(Cons将有elementlist研究所VAR),让你做创建列表:

listWithOne := Cons element: 1 list: EmptyList new. 

headtail方法可以平凡写在Cons类通过返回inst var值。您还可以在EmptyList类中定义headtail方法,以便现在EmptyListCons是多态的。

新增:好吧,只是为了好玩,使用块和数组的实现,实用的风格:

| empty cons head tail test | 
empty := [nil]. 
cons := [:i :j :value :old | [Array with:i with:j with:value with:old]]. 
head := [:list | list value ifNotNil: [:v | v copyFrom:1 to:3]]. 
tail := [:list | list value at: 4]. 

test := cons value: 1 value: 1 value: 'Hi' value: (cons value: 1 value: 2 value: 'Ho' value: empty). 
"Print each one" 
head value: test. 
head value: (tail value: test). 
head value: (tail value: (tail value: test)). 

HTH

+1

我不认为这有帮助。没有必要真正模拟列表数据结构(请参阅我的答案)。 – 2013-04-10 17:19:21