SequenceableCollection为了简单起见,让我实现它:
nextCombination09
| j |
j := self findLast: [:ai | ai < 9] ifAbsent: [^nil].
j + 1 to: self size do: [:i | self at: i put: 0].
self at: j put: (self at: j) + 1
想法如下:使用字典顺序对所有组合进行排序。换句话说:
(a1, ..., an) < (b1, ..., bn)
如果ai = bi对于所有i低于某个索引jwhere aj < bj。
使用此顺序,第一个组合是(0, ..., 0)和最后一个组合(9, ..., 9)。
此外,给定一个组合(a1, ..., an),按此顺序排列的下一个是添加1到最低卓越索引的组合,这是最后一个索引j,其中aj < 9. 例如,下一个 to(2, 3, 8, 9)是(2, 3, 9, 9)因为两者之间不能有任何东西。
一旦我们到达,(9, ..., 9)我们就完成了,并用 回答nil。
请注意,上面的方法修改了接收器,这就是为什么我们必须copy在下面的脚本中。
这是产生所有组合的脚本(n是你的N)
n := <whatever>
array := Array new: n withAll: 0.
combinations := OrderedCollection new: (10 raisedTo: n).
[
combinations add: array copy.
array nextCombination09 notNil] whileTrue.
^combinations
附录
相同的技术可用于其他类似性质的问题。