删除连续多次重复的数字

时间:2012-12-17 18:37:08

标签: groovy

我有收藏品

def list = [4,1,1,1,3,5,1,1]

我需要删除连续重复三次的数字。结果我得到[4,3,5,1,1]。如何在groovy中做到这一点?

3 个答案:

答案 0 :(得分:1)

这可以通过复制列表来完成,同时确保前两个元素与要复制的元素不同。如果是,则删除前两个元素,否则正常复制。

这可以通过inject实现,如下所示:

def list = [4,1,1,1,3,5,1,1]
def result = list.drop(2).inject(list.take(2)) { result, element -> 
    def prefixSize = result.size() - 2
    if ([element] * 2 == result.drop(prefixSize)) { 
        result.take(prefixSize)
    } else {
        result + element
    }
}
assert result == [4,3,5,1,1]

答案 1 :(得分:0)

您可以计算接下来三个元素中的唯一身份大小,并在它们为1时删除它们:

def list = [4,1,1,1,3,5,1,1]
assert removeTriplets(list) == [4,3,5,1,1]

def removeTriplets(list) {
  listCopy = [] + list
  (list.size()-3).times { index ->
    uniques = list[index..(index+2)].unique false
    if (uniques.size() == 1) 
      listCopy = listCopy[0..(index-1)] + listCopy[(index+3)..-1]
  }
  listCopy
}

答案 2 :(得分:0)

另一种选择是使用Run Length Encoding

首先让我们定义一个类来保存我们的对象及其在一行中出现的次数:

class RleUnit {
  def object
  int runLength

  RleUnit( object ) {
    this( object, 1 )
  }

  RleUnit( object, int runLength ) {
    this.object = object
    this.runLength = runLength
  }

  RleUnit inc() {
    new RleUnit( object, runLength + 1 )
  }

  String toString() { "$object($runLength)" }
}

然后我们可以定义一个方法,将List编码为RleUnit个对象的列表:

List<RleUnit> rleEncode( List list ) {
  list.inject( [] ) { r, v ->
    if( r && r[ -1 ].object == v ) {
      r.take( r.size() - 1 ) << r[ -1 ].inc()
    }
    else {
      r << new RleUnit( v )
    }
  }
}

一个获取RleUnit个对象列表并将其解包回原始列表的方法:

List rleDecode( List<RleUnit> rle ) {
  rle.inject( [] ) { r, v ->
    r.addAll( [ v.object ] * v.runLength )
    r
  }
}

然后我们可以对原始列表进行编码:

def list = [ 4, 1, 1, 1, 3, 5, 1, 1 ]
rle = rleEncode( list )

使用Groovy find方法过滤此RleUnit列表:

// remove all elements with a runLength of 3
noThrees = rle.findAll { it.runLength != 3 }
unpackNoThrees = rleDecode( noThrees )
assert unpackNoThrees == [ 4, 3, 5, 1, 1 ]

// remove all elements with a runLength of less than 3
threeOrMore = rle.findAll { it.runLength >= 3 }
unpackThreeOrMore = rleDecode( threeOrMore )
assert unpackThreeOrMore == [ 1, 1, 1 ]