Metode generik yang dapat mengembalikan bilangan bulat acak antara 2 parameter seperti halnya ruby rand(0..n)
.
Ada saran?
Metode generik yang dapat mengembalikan bilangan bulat acak antara 2 parameter seperti halnya ruby rand(0..n)
.
Ada saran?
Jawaban:
Saran saya akan menjadi fungsi ekstensi di IntRange untuk membuat tebusan seperti ini:(0..10).random()
Pada 1.3, Kotlin hadir dengan generator Acak multi-platform sendiri. Ini dijelaskan dalam KEEP ini . Ekstensi yang dijelaskan di bawah sekarang menjadi bagian dari perpustakaan standar Kotlin , cukup gunakan seperti ini:
val rnds = (0..10).random()
Sebelum 1.3, pada JVM kita menggunakan Random
atau bahkan ThreadLocalRandom
jika kita menggunakan JDK> 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Digunakan seperti ini:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Jika Anda ingin fungsi hanya kembali 1, 2, ..., 9
( 10
tidak termasuk), gunakan rentang yang dibangun dengan until
:
(0 until 10).random()
Jika Anda bekerja dengan JDK> 1.6, gunakan ThreadLocalRandom.current()
sebagai ganti Random()
.
Kotlin dan variasi lainnya
Untuk kotlinjs dan kasus penggunaan lainnya yang tidak memungkinkan penggunaan java.util.Random
, lihat alternatif ini .
Juga, lihat jawaban ini untuk variasi saran saya. Ini juga mencakup fungsi ekstensi untuk Char
s acak .
Hasilkan bilangan bulat acak antara from
(inklusif) dan to
(eksklusif)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Int
s acak acak , Anda bisa menggunakan Random # int (size, from, to) sebagai gantinya di java-8 .
Pada kotlin 1.2, Anda dapat menulis:
(1..3).shuffled().last()
Sadarilah itu besar O (n), tetapi untuk daftar kecil (terutama nilai-nilai unik) tidak apa-apa: D
Anda dapat membuat fungsi ekstensi yang mirip dengan java.util.Random.nextInt(int)
tetapi yang mengambil IntRange
alih - alih Int
untuk terikat:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Anda sekarang dapat menggunakan ini dengan Random
contoh apa pun :
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Jika Anda tidak ingin harus mengatur Random
instance Anda sendiri maka Anda dapat menentukan metode kenyamanan menggunakan, misalnya ThreadLocalRandom.current()
,:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Sekarang Anda bisa mendapatkan bilangan bulat acak seperti di Ruby tanpa harus terlebih dahulu mendeklarasikan Random
instance:
rand(5..9) // returns 5, 6, 7, or 8
Kemungkinan Variasi untuk jawaban saya yang lain untuk karakter acak
Untuk mendapatkan Char
s acak , Anda dapat menentukan fungsi ekstensi seperti ini
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()
Jika Anda bekerja dengan JDK> 1.6, gunakan ThreadLocalRandom.current()
sebagai gantiRandom()
.
Untuk kotlinjs dan kasus penggunaan lainnya yang tidak memungkinkan penggunaan java.util.Random
, jawaban ini akan membantu.
Pada 1.3, Kotlin hadir dengan generator Acak multiplatform sendiri. Ini dijelaskan dalam KEEP ini . Anda sekarang dapat langsung menggunakan ekstensi sebagai bagian dari perpustakaan standar Kotlin tanpa mendefinisikannya:
('a'..'b').random()
Membangun dari @ s1m0nw1 jawaban yang sangat baik saya membuat perubahan berikut.
Kode:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Kasus cobaan:
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())
}
)
}
Contoh acak dalam kisaran [1, 10]
val random1 = (0..10).shuffled().last()
atau memanfaatkan Java Random
val random2 = Random().nextInt(10) + 1
Pada 1.3, perpustakaan standar menyediakan dukungan multi-platform untuk tebusan, lihat jawaban ini .
Jika Anda bekerja dengan Kotlin JavaScript dan tidak memiliki akses ke java.util.Random
, yang berikut ini akan berfungsi:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Digunakan seperti ini:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Cara lain untuk mengimplementasikan jawaban s1m0nw1 adalah dengan mengaksesnya melalui variabel. Bukan berarti ini lebih efisien tetapi menghemat Anda dari keharusan mengetik ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
Dan sekarang dapat diakses seperti itu
(1..10).random
Di Kotlin 1.3 Anda bisa melakukannya
val number = Random.nextInt(limit)
Tidak ada metode standar yang melakukan ini tetapi Anda dapat dengan mudah membuat sendiri menggunakan salah satu Math.random()
atau kelas java.util.Random
. Berikut ini adalah contoh menggunakan Math.random()
metode ini:
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) })
}
Ini adalah contoh output:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Lib standar Kotlin tidak menyediakan API Penghasil Angka Acak. Jika Anda tidak berada dalam proyek multi platform, lebih baik menggunakan api platform (semua yang lain menjawab pertanyaan, bicarakan solusi ini) .
Tetapi jika Anda berada dalam konteks multi platform, solusi terbaik adalah menerapkan sendiri secara acak di kotlin murni untuk berbagi generator angka acak yang sama antar platform. Ini lebih mudah untuk dev dan pengujian.
Untuk menjawab masalah ini dalam proyek pribadi saya, saya menerapkan Generator Congruential Kotlin Linear murni . LCG adalah algoritma yang digunakan oleh java.util.Random
. Ikuti tautan ini jika Anda ingin menggunakannya:
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Tujuan implementasi saya nextInt(range: IntRange)
untuk Anda;).
Jaga tujuan saya, LCG baik untuk sebagian besar kasus penggunaan (simulasi, game, dll ...) tetapi tidak cocok untuk penggunaan kriptografis karena dapat diprediksi metode ini.
Jika angka yang ingin Anda pilih tidak berurutan, Anda bisa menggunakan random()
.
Pemakaian:
val list = listOf(3, 1, 4, 5)
val number = list.random()
Mengembalikan salah satu angka yang ada dalam daftar.
Menggunakan fungsi tingkat atas, Anda dapat mencapai sintaks panggilan yang sama persis seperti di Ruby (seperti yang Anda inginkan):
fun rand(s: Int, e: Int) = Random.nextInt(s, e + 1)
Pemakaian:
rand(1, 3) // returns either 1, 2 or 3
Pertama, Anda membutuhkan RNG. Di Kotlin saat ini Anda harus menggunakan platform spesifik (tidak ada Kotlin yang dibangun dalam satu). Untuk JVM itu java.util.Random
. Anda harus membuat instance dan kemudian menelepon random.nextInt(n)
.
Untuk mendapatkan nomor Int acak di Kotlin gunakan metode berikut :
import java.util.concurrent.ThreadLocalRandom
fun randomInt(rangeFirstNum:Int, rangeLastNum:Int) {
val randomInteger = ThreadLocalRandom.current().nextInt(rangeFirstNum,rangeLastNum)
println(randomInteger)
}
fun main() {
randomInt(1,10)
}
// Result – random Int numbers from 1 to 9
Semoga ini membantu.
Anda dapat membuat fungsi ekstensi:
infix fun ClosedRange<Float>.step(step: Float): Iterable<Float> {
require(start.isFinite())
require(endInclusive.isFinite())
require(step.round() > 0.0) { "Step must be positive, was: $step." }
require(start != endInclusive) { "Start and endInclusive must not be the same"}
if (endInclusive > start) {
return generateSequence(start) { previous ->
if (previous == Float.POSITIVE_INFINITY) return@generateSequence null
val next = previous + step.round()
if (next > endInclusive) null else next.round()
}.asIterable()
}
return generateSequence(start) { previous ->
if (previous == Float.NEGATIVE_INFINITY) return@generateSequence null
val next = previous - step.round()
if (next < endInclusive) null else next.round()
}.asIterable()
}
Nilai Float bulat:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Penggunaan metode:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Keluaran:
nilai: 0,0 nilai: 0,1 nilai: 0,2 nilai: 0,3 nilai: 0,4 nilai: 0,5 nilai: 0,6 nilai: 0,7 nilai: 0,8 nilai: 0,9 nilai: 1,0
Kode sumber lengkap. Dapat mengontrol apakah duplikat diizinkan.
import kotlin.math.min
abstract class Random {
companion object {
fun string(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet: List<Char> = ('a'..'z') + ('A'..'Z') + ('0'..'9') // Add your set here.
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
fun alphabet(length: Int, isUnique: Boolean = false): String {
if (0 == length) return ""
val alphabet = ('A'..'Z')
if (isUnique) {
val limit = min(length, alphabet.count())
val set = mutableSetOf<Char>()
do { set.add(alphabet.random()) } while (set.count() != limit)
return set.joinToString("")
}
return List(length) { alphabet.random() }.joinToString("")
}
}
}
Setiap kali ada situasi di mana Anda ingin menghasilkan kunci atau alamat mac yang nomor heksadesimal memiliki digit berdasarkan permintaan pengguna, dan itu juga menggunakan android dan kotlin, maka Anda kode saya di bawah ini membantu Anda:
private fun getRandomHexString(random: SecureRandom, numOfCharsToBePresentInTheHexString: Int): String {
val sb = StringBuilder()
while (sb.length < numOfCharsToBePresentInTheHexString) {
val randomNumber = random.nextInt()
val number = String.format("%08X", randomNumber)
sb.append(number)
}
return sb.toString()
}
menjadi super duper))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random
?