2017-12-21 1 views
0

私はC++で書かれた簡単なプログラムを持っています。これは、乱数を生成し、これらの数字の合計が等しいか、100より大きいコードがどのように見える時に停止:Scalaのループスタイルのプログラムを処理する最良の方法

vector<int> container; 
while(container.sum() <100) 
{ 
    int new_number = rand()%10 + 1 ;// generate a number in range 1 to 10 
    container.push_back(new_number); // add new number to the container 

} 

スカラ座でのタスクを処理するための最良の方法は何ですか? (Whileループを使用しないで?)

FoldLeftまたはFoldRight関数は、ある条件でブレークする機能を持っていないようですか?

+1

あなた自身で何を試しましたか? – cchantep

+0

これらの数字で何をしたいですか?それらの数字をメモリに保存する必要がありますか? – Mzf

答えて

3

は、乱数の無限Streamを作成し(非常に少ないCPUを必要とし、必要なものだけを取り出し、結果をStreamに変換します。

val randoms = Stream.continually(util.Random.nextInt(10)+1) 
val container = randoms.take(randoms.scan(0)(_+_).indexWhere(_>=100)).toVector 

追加ボーナスは合計は、あなたが行くように、すなわち、計算初めから各時間を合計していない、以前の合計に追加されていることです。

1

ここでそれを行うための一つの方法です:

val randomNumberGenerator = new scala.util.Random 
    def sumUntil(list: List[Int]): List[Int] = list match { 
    case exceeds if list.filter(_ > 0).sum > 100 => list 
    case _ => sumUntil(list :+ (randomNumberGenerator.nextInt(10) + 1)) 
    } 

ソリューション説明するために:私たちは、乱数

  • sumUntil意志のパターンマッチを生成するのに役立ちますscala.util.Randomのインスタンスを作成します

    1. を。リストの合計が100を超える場合は、それを返します。
    2. 合計が100を超えない場合は、sumUntilをもう一度呼び出しますが、別の乱数が10以上1以下で生成されます。 _は、「値はもちろん、タイプについても気にしない」ということを覚えておいてください。 _は何かしかしあなたはスカラ座に新しいしている場合は私たちのリストにあるすべての整数の合計が100

    以上である、私はそれが目に少しラフであってもよいことを理解する場合であります読む。以下は、洗練されたバージョンです:

    val randomNumberGenerator = new scala.util.Random 
    
        def sumUntil(list: List[Int]): List[Int] = list match { 
        case exceeds if sumList(list) > 100 => list 
        case _ => sumUntil(appendRandomNumberToList(list)) 
        } 
    
        private def sumList(list: List[Int]): Int = { 
        list.filter(_ > 0).sum 
        } 
    
        private def appendRandomNumberToList(list: List[Int]): List[Int] = { 
        list :+ randomNumberGenerator.nextInt(10) + 1 
        } 
    
  • 2

    は、ここで次のように末尾再帰関数を使用して、whileループを処理するための一つのアプローチです:

    @scala.annotation.tailrec 
    def addToContainer(container: Vector[Int], max: Int): Vector[Int] = { 
        val newContainer = container ++ Vector(scala.util.Random.nextInt(10) + 1) 
    
        if (newContainer.sum >= max) container 
        else addToContainer(newContainer, max) 
    } 
    
    addToContainer(Vector[Int](), 100) 
    // res1: Vector[Int] = Vector(9, 9, 5, 9, 3, 5, 2, 5, 10, 7, 6, 4, 5, 5, 9, 3) 
    
    res1.sum 
    // res2: Int = 96 
    
    +1

    一般に、ループとテールの再帰関数はまったく同じですが、注意が必要です。したがって、別の言語(擬似コードでさえ)でwhileループがある場合は、それを末尾の再帰関数としてscalaに変換することができます(そしてwhileループを作成したかのようにScalaがコンパイルします)。 –

    0
    • ループでコレクションをスキャンする場合は、foldまたはreduceを使用します。
    • カスタム終了条件が必要な場合は、再帰が優先されます。
    関連する問題