与其他人不同,我将假设您想就地完成工作,因为您提到了对索引重新编号的担忧。如果排序是你所关心的那么
1)将要删除的索引粘贴到恒定时间查找集而不是列表中。根据索引的范围,散列集或位集似乎是合适的。2) 以相反的顺序遍历列表缓冲区,删除待删除集中的索引。
scala> val buffer = ListBuffer("a", "b", "c", "d", "e")
buffer: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, b, c, d, e)
scala> val indicesToDelete = BitSet(4, 1)
indicesToDelete: scala.collection.mutable.BitSet = BitSet(1, 4)
scala> for (i <- (buffer.size -1) to 0 by -1) if (indicesToDelete contains i) buffer remove i
scala> buffer
res19: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, c, d)
请注意,虽然这会删除 n log n 类型的索引,但这并不能使其成为线性算法。从类似数组的结构中就地删除并不便宜。每次删除都必须向下复制更高的索引。
要获得索引的线性删除,您需要做一些更复杂的事情,您需要 1) 向前走,根据您迄今为止删除的数字向下复制未删除的元素。完成后 2) 删除前 n 个元素,其中 n 是您删除的数字。
scala> val buffer = ListBuffer("a", "b", "c", "d", "e")
buffer: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, b, c, d, e)
scala> val indicesToDelete = BitSet(4, 1)
indicesToDelete: scala.collection.mutable.BitSet = BitSet(1, 4)
scala> var deleted = 0
deleted: Int = 0
scala> for (i <- 0 until buffer.size)
| if (indicesToDelete contains i) {
| deleted += 1
| } else if (deleted > 0) {
| buffer(i - deleted) = buffer(i)
| }
scala> }
scala> buffer trimEnd deleted
scala> buffer
res0: scala.collection.mutable.ListBuffer[java.lang.String] = ListBuffer(a, c, d)