基于链表的Smalltalk素数生成器报错排查求助
Smalltalk素数生成器(自定义链表实现)错误排查与修复
核心问题分析
- 自定义链表缺失迭代方法:
PrimesGenerator的next方法调用了primes do: [...],但自定义的ConnectedList未实现do:方法,这是运行时错误的直接原因。 - 素数生成逻辑失效:
next方法中value固定为3未递增,递归调用^self next会导致无限循环;whileTrue:的块返回值不符合预期,无法触发正确的循环逻辑。 - 初始化方法不规范:
Node和ConnectedList使用自定义init方法而非Smalltalk标准的initialize,可能导致实例变量未正确初始化。 - 输出逻辑偏差:初始化时已存入素数2,但
next方法仅返回后续生成的素数,导致最终输出缺失第一个素数。
修复方案与完整代码
1. 规范初始化方法
将Node和ConnectedList的初始化方法改为Smalltalk标准的initialize:
Object subclass: #Node instanceVariableNames: 'value next' classVariableNames: '' poolDictionaries: '' category: 'MyApplication' !Node methodsFor: 'initialization'! initialize "Initialize a new node" super initialize. value := nil. next := nil. ^self ! ! !Node methodsFor: 'accessing'! value ^value ! ! !Node methodsFor: 'accessing'! next ^next ! ! !Node methodsFor: 'accessing'! setValue: anObject value := anObject ! ! !Node methodsFor: 'accessing'! setNext: aNode next := aNode ! ! Object subclass: #ConnectedList instanceVariableNames: 'head tail' classVariableNames: '' poolDictionaries: '' category: 'MyApplication' !ConnectedList methodsFor: 'initialization'! initialize "Initialize a new connected list" super initialize. head := nil. tail := nil. ^self ! ! !ConnectedList methodsFor: 'accessing'! head ^head ! ! !ConnectedList methodsFor: 'accessing'! tail ^tail ! ! !ConnectedList methodsFor: 'accessing'! isEmpty ^head isNil ! ! !ConnectedList methodsFor: 'adding'! add: anObject | newNode | newNode := Node new. newNode setValue: anObject. newNode setNext: nil. head isNil ifTrue: [ head := newNode. tail := newNode. ] ifFalse: [ tail setNext: newNode. tail := newNode. ] ^self ! ! !ConnectedList methodsFor: 'enumerating'! do: aBlock "遍历链表并执行传入的块" | currentNode | currentNode := head. [ currentNode isNil ] whileFalse: [ aBlock value: currentNode value. currentNode := currentNode next. ] ! !
2. 修正素数生成逻辑
重写PrimesGenerator的next方法,加入递增逻辑与素数判断优化:
Object subclass: #PrimesGenerator instanceVariableNames: 'primes' classVariableNames: '' poolDictionaries: '' category: 'MyApp-PrimesGenerator' !PrimesGenerator class methodsFor: 'instance creation'! new ^self basicNew initialize ! ! !PrimesGenerator methodsFor: 'initialization'! initialize primes := ConnectedList new. primes add: 2. ^self ! ! !PrimesGenerator methodsFor: 'accessing'! primes ^primes ! ! !PrimesGenerator methodsFor: 'generating primes'! next "返回下一个素数" | value isPrime | value := primes tail value + 1. [ isPrime := true. primes do: [ :each | "优化:只需检查到value的平方根" each * each > value ifTrue: [ ^value ]. value \\ each = 0 ifTrue: [ isPrime := false. value := value + 1. ^self next. ] ]. isPrime ] whileFalse. primes add: value. ^value ! !
3. 调整输出逻辑
确保输出包含初始化的第一个素数:
generator := PrimesGenerator new. "先输出初始素数2" Transcript show: generator primes head value; cr. "生成并输出后续4个素数" 1 to: 4 do: [ :i | Transcript show: generator next; cr. ].
预期输出
2 3 5 7 11
内容的提问来源于stack exchange,提问作者GearedInsanity
相关产品推荐
相关产品推荐

