2017-08-15 317 views

回答

23

生成之間from(含)to(不含)的隨機整數

import java.util.Random 

val random = Random() 

fun rand(from: Int, to: Int) : Int { 
    return random.nextInt(to - from) + from 
} 
+1

如果你想獲得一些隨機的'Int's,你可以使用[Random#int(size,from,to)](http://docs.oracle.com/javase/8/docs/api/java /util/Random.html#ints-long-int-int-)代替[tag:java-8]。 –

+2

此解決方案不適用於Javascript/Native Kotlin。也許讓一個更通用的方法來做到這一點可能會很酷。 :) –

1

首先,您需要一個RNG。在Kotlin中,您目前需要使用平臺特定的平臺(沒有內置Kotlin)。對於JVM,它是java.util.Random。您需要創建一個實例,然後致電random.nextInt(n)

1

有做這個的標準方法,但你可以很容易地使用任何Math.random()或類java.util.Random創建你自己的。下面是使用Math.random()方法的示例:

fun random(n: Int) = (Math.random() * n).toInt() 
fun random(from: Int, to: Int) = (Math.random() * (to - from) + from).toInt() 
fun random(pair: Pair<Int, Int>) = random(pair.first, pair.second) 

fun main(args: Array<String>) { 
    val n = 10 

    val rand1 = random(n) 
    val rand2 = random(5, n) 
    val rand3 = random(5 to n) 

    println(List(10) { random(n) }) 
    println(List(10) { random(5 to n) }) 
} 

這是一個示例輸出:

[9, 8, 1, 7, 5, 6, 9, 8, 1, 9] 
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9] 
84

我建議使用上ClosedRange以下extension功能:

fun ClosedRange<Int>.random() = 
     Random().nextInt(endInclusive - start) + start 

並使用它像這樣:

// will return an `Int` between 0 and 9 (incl.) 
(0..10).random() 

如果您正在使用JDK> = 1.7,請使用ThreadLocalRandom.current()而不是Random()

另請參閱此answer以瞭解我的建議的變體。它還包括隨機Char s的擴展功能。

8

您可以創建一個extension function類似java.util.Random.nextInt(int)而是一個對於其綁定需要一個IntRange而不是Int的:

fun Random.nextInt(range: IntRange): Int { 
    return range.start + nextInt(range.last - range.start) 
} 

現在,您可以用任何Random情況下使用:

val random = Random() 
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8 

如果您不想管理自己的Random實例,則可以使用例如ThreadLocalRandom.current()定義便利方法:

fun rand(range: IntRange): Int { 
    return ThreadLocalRandom.current().nextInt(range) 
} 

現在,你可以得到一個隨機整數,你在Ruby中會,而不必首先聲明自己一個Random實例:

rand(5..9) // returns 5, 6, 7, or 8 
4

大廈關閉@s1m0nw1優秀的答案我做了如下修改。

  1. (0 ..N)在科特林意味着包容
  2. (0到N)在科特林意味着獨家
  3. 使用的隨機比如一個單獨的對象(可選)

代碼:

private object RandomRangeSingleton : Random() 

fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start 

測試案例:

fun testRandom() { 
     Assert.assertTrue(
       (0..1000).all { 
        (0..5).contains((0..5).random()) 
       } 
     ) 
     Assert.assertTrue(
       (0..1000).all { 
        (0..4).contains((0 until 5).random()) 
       } 
     ) 
     Assert.assertFalse(
       (0..1000).all { 
        (0..4).contains((0..5).random()) 
       } 
     ) 
    } 
2

可能的變化我的回答above

a)如果你想0..10.random()也包括價值10,以下變化是必要的:

fun ClosedRange<Int>.random() = 
     Random().nextInt(endInclusive + 1 - start) + start 

b)爲了獲得隨機Char S,你可以像這樣定義一個擴展功能

fun ClosedRange<Char>.random(): Char = 
     (Random().nextInt(endInclusive.toInt() + 1 - start.toInt()) + start.toInt()).toChar() 

// will return a `Char` between A and Z (incl.) 
('A'..'Z').random() 

如果你使用JDK> = 1.7下工作,使用ThreadLocalRandom.current()代替Random()

1

使用頂級功能,可以實現完全相同的調用語法在紅寶石(如你所願):

fun rand(s: Int, e: Int) = Random().nextInt(e + 1 - s) + s 

用法:

rand(1, 3) // returns either 1, 2 or 3 
1

如果數字要選擇不連續,可以在列表中定義自己的擴展功能:

fun List<*>.randomElement() 
    = if (this.isEmpty()) null else this[Random().nextInt(this.size)] 

用法:

val list = listOf(3, 1, 4, 5) 
val number = list.randomElement() 

返回列表中的一個數字。

1

Kotlin標準庫不提供隨機數生成器API。如果您不在多平臺項目中,最好使用平臺api (關於此解決方案的所有其他問題的答案)

但是,如果您處於多平臺環境中,最好的解決方案是在純kotlin中自己實現隨機,以便在平臺之間共享相同的隨機數生成器。開發和測試更簡單。

要回答我個人項目中的這個問題,我實現了一個純Kotlin Linear Congruential Generator。 LCG是由java.util.Random使用的算法。如果你想使用它,請點擊此鏈接: https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4

我的實施目的nextInt(range: IntRange)爲你;)。

注意我的目的,LCG適用於大多數使用案例(模擬,遊戲等)但由於此方法的可預測性而不適合加密使用。

1

由於科特林1.2的,你可以寫:

(1..3).shuffled().last()

要知道它的大O(n)的,但對於一個小清單(尤其是唯一值)這是正常的:d

相關問題