3

3 または 5 で割り切れる 1 から 1000 までのすべての数値のリストを取得する関数型アプローチを scala で作成しようとしています。

これが私がこれまでに持っているものです:

  def getListOfElements(): List[Int] = { 
  val list = List()

    for (i <- 0 until 1000) {
        //list.
  } 
  list match {
    case Nil => 0
  } 
  list
}  

for ループは命令型のアプローチのように思えますが、ケース クラスで何を照合すればよいかわかりません。ガイダンスをお願いします。

4

6 に答える 6

7

式でそれを行う方法は次のとおりforです。

for( i <- 1 to 1000 if i % 3 == 0 || i % 5 == 0) yield i

これは与える:

 scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 6, 9, 10, 12, 15, 18, 20, 21...

数値でフィルタリングする別のアプローチを次にRange示します。

scala> 1 to 1000
res0: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3, 4, 5, 6, 7, 8, 9, 10...


scala> res0.filter(x => x % 3 == 0 || x % 5 == 0)
res1: scala.collection.immutable.IndexedSeq[Int] = Vector(3, 5, 6, 9, 10, 12, 15, 18, 20, 21...

本当にList戻り値に が必要な場合は、 を使用しますtoList。例えばres0.toList

于 2012-12-12T17:27:48.553 に答える
4
(Range(3, 1000, 3) ++ Range(5, 1000, 5)).toSet.toList.sorted

ソートは省略可能です。

于 2012-12-12T17:40:48.557 に答える
3

別のアプローチ:

(1 to 1000).filter(i => i % 3 == 0 || i % 5 == 0)
于 2012-12-12T17:56:35.577 に答える
2

ブライアンが私を打ち負かしたようです:)

ここでは、パフォーマンスを向上させるために Stream の方が望ましいかもしれないと言いたいと思いました:

val x = (1 until 1000).toStream           //> x  : scala.collection.immutable.Stream[Int] = Stream(1, ?)
x filter (t=>(t%3==0)||(t%5==0))          //> res0: scala.collection.immutable.Stream[Int] = Stream(3, ?)
于 2012-12-12T17:31:16.633 に答える
2

projecteuler.net の問題でも、最後にこれらの数値の合計が必要です。

「1000 未満の 3 または 5 の倍数の合計を求めよ。」

object prb1 {
  def main(args: Array[String]) {
    val retval = for{ a <- 1 to 999
                      if a % 3 == 0 || a % 5 == 0
    } yield a
    val sum = retval.reduceLeft[Int](_+_)
    println("The sum of all multiples of 3 and 5 below 1000 is " + sum)
  }
}

正解は233168のはずです

于 2014-12-22T23:43:41.450 に答える
0

分割またはリストの再作成なしでは、答えはありません。再帰による答えはありません。

また、ベンチマークはありますか?

@scala.annotation.tailrec def div3or5(list: Range, result: List[Int]): List[Int] = {
  var acc = result
  var tailList = list
  try {
    acc = list.drop(2).head :: acc   // drop 1 2 save 3
    acc = list.drop(4).head :: acc   // drop 3 4 save 5
    acc = list.drop(5).head :: acc   // drop 5 save 6 
    acc = list.drop(8).head :: acc   // drop 6 7 8 save 9
    acc = list.drop(9).head :: acc   // drop 9 save 10
    acc = list.drop(11).head :: acc  // drop 10 11 save 12
    acc = list.drop(14).head :: acc  // drop 12 13 14 save 15 
    tailList = list.drop(15)         // drop 15             
  } catch {
    case e: NoSuchElementException => return acc // found
  }
  div3or5(tailList, acc) // continue search  
}

div3or5(Range(1, 1001), Nil)

編集

scala> val t0 = System.nanoTime; div3or5(Range(1, 10000001), Nil).toList; 
(System.nanoTime - t0) / 1000000000.0
t0: Long = 1355346955285989000
res20: Double = 6.218004

私には良さそうな答えの1つ:

scala> val t0 = System.nanoTime; Range(1, 10000001).filter(i => 
i % 3 == 0 || i % 5 == 0).toList; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space

別のもの:

scala> val t0 = System.nanoTime; (Range(1, 10000001).toStream filter (
(t: Int)=>(t%3==0)||(t%5==0))).toList ; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space

最初の1つ:

scala> val t0 = System.nanoTime; (for( i <- 1 to 10000000 if i % 3 == 0 || 
i % 5 == 0) yield i).toList; (System.nanoTime - t0) / 1000000000.0
java.lang.OutOfMemoryError: Java heap space

Scala が Vector -> List などを最適化しないのはなぜですか?

于 2012-12-12T20:51:01.070 に答える