1

コレクションがあります

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

そして、3回続けて繰り返される数字を削除する必要があります。その結果、[4,3,5,1,1]を取得する必要があります。Groovyでこれを行う方法は?

4

3 に答える 3

1

これは、前の2つの要素がコピーする要素と同じでないことを確認しながら、リストをコピーすることで実行できます。そうである場合は、前の2つの要素を削除します。そうでない場合は、通常どおりにコピーします。

これは、次のように実装できます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]
于 2012-12-17T19:20:35.397 に答える
0

次の3つの要素で一意のサイズを計算し、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
}
于 2012-12-17T19:39:01.367 に答える
0

別のオプションは、ランレングスエンコーディングを使用することです

まず、オブジェクトを保持するクラスと、オブジェクトが連続して発生する回数を定義しましょう。

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)" }
}

次に、リストを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 )

そして、このRleUnitリストをGroovyfindメソッドでフィルタリングします。

// 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 ]
于 2012-12-18T10:31:45.657 に答える