Một phương thức chung có thể trả về một số nguyên ngẫu nhiên giữa 2 tham số như ruby thực hiện với rand(0..n)
.
Bất kì lời đề nghị nào?
Một phương thức chung có thể trả về một số nguyên ngẫu nhiên giữa 2 tham số như ruby thực hiện với rand(0..n)
.
Bất kì lời đề nghị nào?
Câu trả lời:
Đề xuất của tôi sẽ là một chức năng mở rộng trên IntRange để tạo các randoms như thế này:(0..10).random()
Kể từ 1.3, Kotlin đi kèm với trình tạo ngẫu nhiên đa nền tảng của riêng mình. Nó được mô tả trong KEEP này . Phần mở rộng được mô tả dưới đây hiện là một phần của thư viện tiêu chuẩn Kotlin , chỉ cần sử dụng nó như thế này:
val rnds = (0..10).random()
Trước 1.3, trên JVM, chúng tôi sử dụng Random
hoặc ngay cả ThreadLocalRandom
khi chúng tôi sử dụng JDK> 1.6.
fun IntRange.random() =
Random().nextInt((endInclusive + 1) - start) + start
Được sử dụng như thế này:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Nếu bạn chỉ muốn hàm trả về 1, 2, ..., 9
( 10
không bao gồm), hãy sử dụng một phạm vi được xây dựng với until
:
(0 until 10).random()
Nếu bạn đang làm việc với JDK> 1.6, hãy sử dụng ThreadLocalRandom.current()
thay vì Random()
.
KotlinJs và các biến thể khác
Đối với kotlinjs và các trường hợp sử dụng khác không cho phép sử dụng java.util.Random
, hãy xem phương án này .
Ngoài ra, xem câu trả lời này cho các biến thể của đề nghị của tôi. Nó cũng bao gồm một hàm mở rộng cho Char
s ngẫu nhiên .
Tạo một số nguyên ngẫu nhiên giữa from
(bao gồm) và to
(độc quyền)
import java.util.Random
val random = Random()
fun rand(from: Int, to: Int) : Int {
return random.nextInt(to - from) + from
}
Int
s ngẫu nhiên trong phạm vi, bạn có thể sử dụng Random # int (kích thước, từ, đến) thay vào đó trong java-8 .
Kể từ kotlin 1.2, bạn có thể viết:
(1..3).shuffled().last()
Chỉ cần lưu ý rằng đó là O (n) lớn, nhưng đối với một danh sách nhỏ (đặc biệt là các giá trị duy nhất) thì không sao: D
Bạn có thể tạo một chức năng mở rộng tương tự java.util.Random.nextInt(int)
nhưng một chức năngIntRange
thay thế cho một Int
ràng buộc của nó:
fun Random.nextInt(range: IntRange): Int {
return range.start + nextInt(range.last - range.start)
}
Bây giờ bạn có thể sử dụng điều này với bất kỳ Random
trường hợp nào :
val random = Random()
println(random.nextInt(5..9)) // prints 5, 6, 7, or 8
Nếu bạn không muốn phải quản lý Random
cá thể của riêng mình thì bạn có thể xác định phương thức tiện lợi bằng cách sử dụng, ví dụ ThreadLocalRandom.current()
:
fun rand(range: IntRange): Int {
return ThreadLocalRandom.current().nextInt(range)
}
Bây giờ bạn có thể nhận được một số nguyên ngẫu nhiên như trong Ruby mà không cần phải tự khai báo một Random
thể hiện:
rand(5..9) // returns 5, 6, 7, or 8
Biến thể có thể cho câu trả lời khác của tôi cho ký tự ngẫu nhiên
Để có được Char
s ngẫu nhiên , bạn có thể xác định hàm mở rộng như thế này
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()
Nếu bạn đang làm việc với JDK> 1.6, hãy sử dụng ThreadLocalRandom.current()
thay vì Random()
.
Đối với kotlinjs và các trường hợp sử dụng khác không cho phép sử dụng java.util.Random
, câu trả lời này sẽ có ích.
Kể từ 1.3, Kotlin đi kèm với trình tạo ngẫu nhiên đa nền tảng của riêng nó. Nó được mô tả trong KEEP này . Bây giờ bạn có thể trực tiếp sử dụng tiện ích mở rộng như một phần của thư viện chuẩn Kotlin mà không cần xác định nó:
('a'..'b').random()
Xây dựng câu trả lời xuất sắc @ s1m0nw1 Tôi đã thực hiện các thay đổi sau.
Mã số:
private object RandomRangeSingleton : Random()
fun ClosedRange<Int>.random() = RandomRangeSingleton.nextInt((endInclusive + 1) - start) + start
Trường hợp thử nghiệm:
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())
}
)
}
Các ví dụ ngẫu nhiên trong phạm vi [1, 10]
val random1 = (0..10).shuffled().last()
hoặc sử dụng Java Random
val random2 = Random().nextInt(10) + 1
Kể từ 1.3, thư viện tiêu chuẩn cung cấp hỗ trợ đa nền tảng cho các randoms, hãy xem câu trả lời này .
Nếu bạn đang làm việc với JavaScript Kotlin và không có quyền truy cập java.util.Random
, những điều sau đây sẽ hoạt động:
fun IntRange.random() = (Math.random() * ((endInclusive + 1) - start) + start).toInt()
Được sử dụng như thế này:
// will return an `Int` between 0 and 10 (incl.)
(0..10).random()
Một cách khác để thực hiện câu trả lời của s1m0nw1 là truy cập nó thông qua một biến. Không phải là nó hiệu quả hơn nhưng nó giúp bạn không phải gõ ().
val ClosedRange<Int>.random: Int
get() = Random().nextInt((endInclusive + 1) - start) + start
Và bây giờ nó có thể được truy cập như vậy
(1..10).random
Không có phương pháp tiêu chuẩn nào thực hiện điều này nhưng bạn có thể dễ dàng tạo riêng của mình bằng cách sử dụng Math.random()
hoặc lớp java.util.Random
. Dưới đây là một ví dụ sử dụng Math.random()
phương thức:
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) })
}
Đây là một đầu ra mẫu:
[9, 8, 1, 7, 5, 6, 9, 8, 1, 9]
[5, 8, 9, 7, 6, 6, 8, 6, 7, 9]
Liblin tiêu chuẩn lib không cung cấp API Trình tạo số ngẫu nhiên. Nếu bạn không tham gia dự án đa nền tảng, tốt hơn là sử dụng api nền tảng (tất cả các câu trả lời khác của câu hỏi đều nói về giải pháp này) .
Nhưng nếu bạn đang ở trong một bối cảnh đa nền tảng, giải pháp tốt nhất là tự mình thực hiện ngẫu nhiên trong kotlin thuần túy để chia sẻ cùng một trình tạo số ngẫu nhiên giữa các nền tảng. Nó đơn giản hơn cho dev và thử nghiệm.
Để trả lời cho vấn đề này trong dự án cá nhân của tôi, tôi triển khai một Trình tạo cộng tuyến tuyến tính thuần túy của Kotlin . LCG là thuật toán được sử dụng bởi java.util.Random
. Theo liên kết này nếu bạn muốn sử dụng nó:
https://gist.github.com/11e5ddb567786af0ed1ae4d7f57441d4
Mục đích thực hiện của tôi nextInt(range: IntRange)
cho bạn;).
Hãy quan tâm đến mục đích của tôi, LCG tốt cho hầu hết các trường hợp sử dụng (mô phỏng, trò chơi, v.v ...) nhưng không phù hợp để sử dụng mật mã vì khả năng dự đoán của phương pháp này.
Không cần phải sử dụng các chức năng mở rộng tùy chỉnh nữa. IntRange hiện có random()
chức năng mở rộng.
val randomNumber = (0..10).random()
Đầu tiên, bạn cần có RNG. Trong Kotlin hiện tại bạn cần sử dụng các nền tảng cụ thể (không có Kotlin được tích hợp trong một). Đối với JVM, nó java.util.Random
. Bạn sẽ cần tạo một thể hiện của nó và sau đó gọi random.nextInt(n)
.
Để có được số Int ngẫu nhiên trong Kotlin, hãy sử dụng phương pháp sau :
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
Hi vọng điêu nay co ich.
Bạn có thể tạo một chức năng mở rộng:
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()
}
Giá trị phao tròn:
fun Float.round(decimals: Int = DIGITS): Float {
var multiplier = 1.0f
repeat(decimals) { multiplier *= 10 }
return round(this * multiplier) / multiplier
}
Cách sử dụng:
(0.0f .. 1.0f).step(.1f).forEach { System.out.println("value: $it") }
Đầu ra:
giá trị: 0,0 giá trị: 0,1 giá trị: 0,2 giá trị: 0,3 giá trị: 0,4 giá trị: 0,5 giá trị: 0,6 giá trị: 0,7 giá trị: 0,8 giá trị: 0,9 giá trị: 1,0
Mã nguồn đầy đủ. Có thể kiểm soát xem các bản sao được cho phép.
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("")
}
}
}
Bất cứ khi nào có tình huống bạn muốn tạo địa chỉ khóa hoặc mac là số thập lục phân có các chữ số dựa trên nhu cầu của người dùng và việc sử dụng android và kotlin cũng vậy, thì mã dưới đây của tôi sẽ giúp bạn:
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()
}
trở thành siêu lừa đảo))
fun rnd_int(min: Int, max: Int): Int {
var max = max
max -= min
return (Math.random() * ++max).toInt() + min
}
java.util.Random
?