リストに要素をランダムに挿入する方法

Aug 22 2020

List[Int]lが与えられた場合、新しい要素elemList[Int]lにランダムに挿入するにはどうすればよいですか?

def randomInsert(l: List[Int], elem: Int): List[Int] = ???

回答

3 ValyDia Aug 22 2020 at 11:39

これは、最初にランダムなインデックスをリストに選択してから、そのインデックスに新しい要素を挿入することで実行できます。また、これは一般的な方法で行うことができます。

import scala.util.Random

def randomInsert[A](l: List[A], elem: A): List[A] = {
  val random = new Random
  val randomIndex = random.nextInt(l.length + 1)
  l.patch(randomIndex, List(elem), 0)
}

使用法:

scala>randomInsert(List(1,2,3,4,5),100)
res2: List[Int] = List(1, 2, 3, 4, 5, 100)

scala>randomInsert(List(1,2,3,4,5),100)
res3: List[Int] = List(100, 1, 2, 3, 4, 5)

scala>randomInsert(List(1,2,3,4,5),100)  
res4: List[Int] = List(1, 2, 100, 3, 4, 5)

このメソッドを使用して、いくつかの要素を再帰的に追加できます。

import scala.util.Random
import scala.annotation.tailrec

def randomInsert[A](l: List[A], elem: A, elems: A*): List[A] = {
  val random = new Random

  @tailrec
  def loop(elemToInsert: List[A], acc: List[A]): List[A] = 
    elemToInsert match {
       case Nil => acc
       case head :: tail =>
         val randomIndex = random.nextInt(acc.length + 1)
         loop(tail, acc.patch(randomIndex, List(head), 0))
    }
  
  loop(elem :: elems.toList, l)
}

使用法:

scala>randomInsert(List(1,2,3,4,5),100,101,102)
res10: List[Int] = List(1, 2, 101, 3, 4, 5, 100, 102)

scala>randomInsert(List(1,2,3,4,5),100,101,102)
res11: List[Int] = List(1, 2, 102, 100, 101, 3, 4, 5)

scala>randomInsert(List(1,2,3,4,5),100,101,102)  
res12: List[Int] = List(1, 2, 3, 4, 100, 5, 102, 101)

編集:コメントによると、これを行うためのより効率的な方法は、両方のリストを結合し、結合されたものをシャッフルすることです-そうすることによって、リストの元の順序を失う可能性があることに注意してください:


import scala.util.Random

def randomInsert[A](l: List[A], elem: A, elems: A*): List[A] = {
 Random.shuffle((elem :: elems.toList) reverse_::: l)
}