Smalltalk中子字符串的索引

use*_*565 5 string smalltalk visualworks pharo dolphin-smalltalk

似乎Smalltalk实现错过了一个算法,该算法返回String中子字符串的所有索引.最相似的只返回一个元素的索引,例如:firstIndexesOf:in:,findSubstring:,findAnySubstring:variants.

Ruby中实现,但第一个依赖于Ruby hack,第二个不能忽略重叠的字符串,最后一个使用Enumerator类,我不知道如何转换为Smalltalk.我想知道这个Python实现是否是最好的开始路径,因为考虑两种情况,重叠或不重叠,并且不使用正则表达式.

我的目标是找到一个提供以下行为的包或方法:

'ABDCDEFBDAC' indicesOf: 'BD'. "#(2 8)"
Run Code Online (Sandbox Code Playgroud)

考虑重叠时:

'nnnn' indicesOf: 'nn' overlapping: true. "#(0 2)"
Run Code Online (Sandbox Code Playgroud)

不考虑重叠时:

'nnnn' indicesOf 'nn' overlapping: false. "#(0 1 2)"
Run Code Online (Sandbox Code Playgroud)

在Pharo中,当在Playground中选择文本时,扫描程序会检测子字符串并突出显示匹配项.但是我找不到这个的String实现.

到目前为止,我的最大努力导致了String(Pharo 6)中的这种实现:

indicesOfSubstring: subString
  | indices i |

  indices := OrderedCollection new: self size.
  i := 0.
  [ (i := self findString: subString startingAt: i + 1) > 0 ] whileTrue: [
    indices addLast: i ].
  ^ indices
Run Code Online (Sandbox Code Playgroud)

Lea*_*lia 5

首先让我澄清一下Smalltalk集合是基于1的,而不是基于0的.因此,您的示例应该阅读

'nnnn' indexesOf: 'nn' overlapping: false. "#(1 3)"
'nnnn' indexesOf: 'nn' overlapping: true. "#(1 2 3)"
Run Code Online (Sandbox Code Playgroud)

请注意,我也注意到了@ lurker的观察(并且也调整了选择器).

现在,从您的代码开始,我将更改如下:

indexesOfSubstring: subString overlapping: aBoolean
  | n indexes i |
  n := subString size.
  indexes := OrderedCollection new.                            "removed the size"
  i := 1.                                                      "1-based"
  [
    i := self findString: subString startingAt: i.             "split condition"
    i > 0]
  whileTrue: [
    indexes add: i.                                            "add: = addLast:"
    i := aBoolean ifTrue: [i + 1] ifFalse: [i + n]].           "new!"
  ^indexes
Run Code Online (Sandbox Code Playgroud)

确保你写了一些单元测试(并且不要忘记练习边框情况!)

  • @ user1000565请为这个有趣的问题打开另一个问题. (3认同)