问题
I'd like to generate the following number sequence in one go using a functional initialization construct:
Array(0, 0, 0, 0, 3, 3, 6, 6, 9, 9, ..., n*3, n*3)
One way is to do:
Array.fill[Int](2)(0) ++ Array.tabulate(4)(_*3)
but I'd need to double each value of the second part of the construct i.e. to get 0, 0
then 3, 3
etc. How can I duplicate the values of the second construct?
I also couldn't figure out a mathematical function that would generate such sequence.
回答1:
Consider tail-recursive solution for single pass
def pattern(n: Int): List[Int] = {
@tailrec def run(n: Int, acc: List[Int]): List[Int] = {
n match {
case 0 => 0 :: 0 :: 0 :: 0 :: acc
case i => run(i - 1, (i * 3) :: (i * 3) :: acc)
}
}
run(n-1, Nil)
}
回答2:
Array(0,0) ++ (0 to 2*n).map(_ / 2 * 3)
回答3:
You can do this:
def create(n: Int): Array[Int] =
Array.tabulate(n)(i => Array.fill(if (i == 0) 4 else 2)(3 * i)).flatten
However, Arrays are not the best data type for flattening.
回答4:
This is a possible solution using flatMap
:
Array.fill[Int](2)(0) ++ Array.tabulate(4)(_*3).flatMap(x => Array(x, x))
回答5:
jmh benchmark of answers
@State(Scope.Benchmark)
@BenchmarkMode(Array(Mode.Throughput))
class So59902144 {
def Luis(n: Int) = Array.tabulate(n)(i => Array.fill(if (i == 0) 4 else 2)(3 * i)).flatten
def Dima(n: Int) = Array(0,0) ++ (0 until 2*n).map(_ / 2 * 3)
def SkyWalker(n: Int) = Array.fill[Int](2)(0) ++ Array.tabulate(n)(_*3).flatMap(x => Array(x, x))
def MarioGalic(n: Int) = {
@tailrec def run(n: Int, acc: List[Int]): List[Int] = {
n match {
case 0 => 0 :: 0 :: 0 :: 0 :: acc
case i => run(i - 1, (i * 3) :: (i * 3) :: acc)
}
}
run(n-1, Nil)
}
val n = 10000
@Benchmark def _Luis = Luis(n)
@Benchmark def _Dima = Dima(n)
@Benchmark def _SkyWalker = SkyWalker(n)
@Benchmark def _MarioGalic = MarioGalic(n)
}
sbt "jmh:run -i 5 -wi 2 -f 1 -t 1 -prof gc bench.So59902144"
[info] Benchmark Mode Cnt Score Error Units
[info] So59902144._Dima thrpt 5 5178.171 ± 837.780 ops/s
[info] So59902144._Luis thrpt 5 3649.262 ± 309.027 ops/s
[info] So59902144._MarioGalic thrpt 5 10926.546 ± 3587.691 ops/s
[info] So59902144._SkyWalker thrpt 5 6088.413 ± 474.100 ops/s
来源:https://stackoverflow.com/questions/59902144/generate-a-custom-pattern-number-sequence-in-one-go