bugfix> scala > 投稿

次の番号のシーケンスがあります:[19、23、24、31、126、127、155、159、160、161]。グループサイズが>の場合、各グループの値の差が1になるように、隣接する値の差に従ってこのシーケンスをグループ化する必要があります。1。

Pythonでは、次のように書きます。

outliers = [19, 23, 24, 31, 126, 127, 155, 159, 160, 161]
chains = [[i for i in list(map(itemgetter(1), g))]
           for _, g in itertools.groupby(enumerate(outliers),
                                         lambda x: x[0]-x[1])]
# [[19], [23, 24], [31], [126, 127], [155], [159, 160, 161]]

きれいです。しかし、条件付きのループに戻ることなく、これをScalaでどのように行うことができますか?私は zipWithIndex で何かをしようとしてきたおよび groupBy これまでのところメソッドはありません:(

回答 2 件
  • あなたは fold できます  シーケンスに沿って、あなたが行くように結果を構築します。

    outliers.foldRight(List.empty[List[Int]]) {case (n, acc) =>
      if (acc.isEmpty) List(List(n))
      else if (acc(0)(0) == n+1) (n :: acc.head) :: acc.tail
      else List(n) :: acc
    }
    //res0: List[List[Int]] = List(List(19), List(23, 24), List(31), List(126, 127), List(155), List(159, 160, 161))
    
    

  • 再帰が条件と一致するかどうかはわかりませんが、最終的にはO(n)です。

    def rec(source: List[Int], temp: List[Int], acc: List[List[Int]]): List[List[Int]] = source match {
        case Nil => acc
        case x :: xs => {
            if (xs.nonEmpty && xs.head - x == 1) rec(xs, temp :+ x, acc)
            else rec(xs, List(), acc :+ (temp :+ x))
        }
    }
    val outliers = List(19, 23, 24, 31, 126, 127, 155, 159, 160, 161)
    rec(outliers, List[Int](), List[List[Int]]())
    
    

あなたの答え