我在使用Smalltalk方面遇到了麻烦。我试图用从文件中读取的数字填充数组,但它似乎不起作用。我尝试了很多选择,我希望有人能向我解释我做错了什么。
Object subclass: #MyStack
instanceVariableNames:'anArray aStack'
classVariableNames:''
poolDictionaries:''
!
MyStack class comment: 'Creates a Stack Class.'
!
!
MyStack methodsFor: 'initialize Stack'
!
new "instance creation"
^ super new.
!
init "initialization"
anArray := Array new: 32.
aStack := 0.
! !
!MyStack methodsFor: 'methods for stacks' !
pop "Removes the top entry from the stack"
| item |
item := anArray at: aStack.
aStack := aStack - 1.
!
push: x "Pushes a new entry onto the stack"
aStack := aStack + 1.
anArray at:aStack put:x.
!
top "Returns the current top of the stack"
^anArray at: aStack.
!
empty "True if the stack is empty"
^aStack = 0.
!
full "True if the stack is full"
^aStack = 32.
!
printOn: aStream "Prints entire stack one entry per line, starting the top entry"
aStream show: 'Stack:'.
aStack to:1 by:-1 do:[:i |(anArray at:i) printOn:aStream. ].
aStream show: ''
! !
"----------------------------------------------------------------------------------"
Object subclass: #IOExample
instanceVariableNames: 'input output'
classVariableNames: ''
poolDictionaries: ''
!
IOExample class comment: '
basic I/O.
'
!
!
IOExample methodsFor: 'initialize'
!
new
^ super new.
!
init
[ input := FileSelectionBrowser open asFilename readStream. ]
on: Error
do: [ :exception |
Dialog warn: 'Unable to open file'.
exception retry.
].
[ output := FileSelectionBrowser open asFilename writeStream. ]
on: Error
do: [ :exception |
Dialog warn: 'Unable to open file'.
exception retry.
].
! !
!
IOExample methodsFor: 'copy input to output turning :: into :'
!
copy
| data lookAhead theStack myStack|
[ input atEnd ] whileFalse: [
data := input next.
(data isKindOf: Integer)
ifTrue: [
(input atEnd) ifFalse: [
"myStack push: data."
lookAhead = input peek.
(lookAhead asCharacter isDigit)
ifTrue: [
]
].
].
output show: myStack.
].
input close.
output close.
! !
答案 0 :(得分:3)
您是否尝试过运行此代码?如果你这样做,我很惊讶你没有收到由于#2下面的编译警告。
#copy
中存在许多问题(除了我不明白它究竟在做什么之外)...
data isKindOf: Integer
。但后来你把它视为一个角色流:lookAhead asCharacter isDigit
。如果第一个条件为真,让你越过那个点,第二个条件永远不会,因为你将匹配[0-9],这不是数字的ASCII值。lookAhead = input peek
。在这里,您将未初始化的lookAhead
(nil
)与偷看的值进行比较,然后丢弃结果。我认为你的意思是lookAhead := input peek
。ifTrue: [ ]
。你想在那里做什么?答案 1 :(得分:2)
Justin,让我试着帮助你完成课程MyStack
,并根据你的例子推荐另一个答案。
我已将您的代码分成片段并附加我的评论。
片段A:
Object subclass: #MyStack
instanceVariableNames:'anArray aStack'
classVariableNames:''
poolDictionaries:''
A的评论:
Smalltalker会使用没有不确定文章a
或an
Object subclass: #MyStack
instanceVariableNames:'array stack'
classVariableNames:''
poolDictionaries:''
片段B:
MyStack class comment: 'Creates a Stack Class.'
B的评论:
这很奇怪。我原本期望这样做(没有class
):
MyStack comment: 'Creates a Stack Class.'
片段C:
MyStack methodsFor: 'initialize Stack'
new "instance creation"
^ super new.
C:*
的评论此代码将new
放在类的实例端,这没有任何意义,因为您通常会将new
发送给类而不是其实例。正确的表单需要添加class
:
MyStack class methodsFor: 'initialize Stack'
new
^super new.
您忘记发送初始化方法(但请参阅下面的片段D)
new
^super new init.
片段D:
init "initialization"
anArray := Array new: 32.
aStack := 0.
D的评论:
在Smalltalk中,人们使用选择器initialize
,因此它可以发送超级优先
initialize
super initialize.
array := Array new: 32.
stack := 0.
请注意,此更改还需要将new
写为
new
^super new initialize.
但是,如果您的方言默认情况下已发送initialize
方法,则应从您的班级中移除new
的实施。
片段E:
pop "Removes the top entry from the stack"
| item |
item := anArray at: aStack.
aStack := aStack - 1.
E的评论:
您忘了回答刚刚弹出的item
pop
| item |
item := array at: stack.
stack := stack - 1.
^item
片段F:
push: x "Pushes a new entry onto the stack"
aStack := aStack + 1.
anArray at:aStack put:x.
对F的评论:
这没关系。但请注意,堆栈将拒绝超出32的限制推送任何项目。
push: x
stack := stack + 1.
array at: stack put: x.
片段G:
top "Returns the current top of the stack"
^anArray at: aStack.
empty "True if the stack is empty"
^aStack = 0.
full "True if the stack is full"
^aStack = 32.
G的评论:
这些也可以。但是,empty
的更合适的名称可能是isEmpty
,因为所有集合都理解这种多态消息。同样,full
的推荐选择器为isFull
:
top
^array at: aStack.
isEmpty
^stack = 0.
isFull
^stack = 32.
另请注意,isFull
重复您在初始化代码中使用的魔术常量32。这不是一个好主意,因为如果你将来改变主意并决定用64改变32,你将不得不修改两种方法而不仅仅是一种方法。你可以用这种方式消除这种重复
isFull
^stack = array size.
片段H:
printOn: aStream
"Prints entire stack one entry per line, starting the top entry"
aStream show: 'Stack:'.
aStack to:1 by:-1 do:[:i |(anArray at:i) printOn:aStream. ].
aStream show: ''
对H的评论:
这段代码的最后一行是多余的,我会摆脱它。但是,您可能希望使用空格
分隔下一个项目printOn: aStream
stream show: 'Stack:'.
stack to: 1 by: -1 do:[:i |
aStream space.
(array at: i) printOn: aStream].