Cách chọn ngẫu nhiên một phần tử từ một mảng


94

Tôi đang tìm giải pháp để chọn số ngẫu nhiên từ một mảng số nguyên.

Ví dụ tôi có một mảng new int[]{1,2,3}, làm thế nào tôi có thể chọn một số ngẫu nhiên?


Câu trả lời:


181
public static int getRandom(int[] array) {
    int rnd = new Random().nextInt(array.length);
    return array[rnd];
}

2
vâng, nhưng bạn phải nói rằng đó generatorlà một ví dụ củajava.util.Random
stivlo

25
Tôi sẽ không tạo Random()mỗi khi bạn chạy hàm: trình tạo ngẫu nhiên phải có lịch sử. Nếu không, nó cực kỳ dễ đoán. Nó hoàn toàn không phải là một vấn đề trong trường hợp này - nhưng cần đề cập rằng array[(int)(System.currentTimeMillis() % array.length)]nó cũng tốt như giải pháp được đề xuất.
alf

4
@alf, điều đó còn lâu mới tốt như giải pháp được đề xuất. new Random()cố gắng tạo một cá thể có hạt giống khác với bất kỳ cá thể nào đã tạo trước đó Random. Cách tiếp cận của bạn sẽ phá vỡ một cách khủng khiếp chỉ bằng cách gọi hàm hai lần trong thời gian ngắn.
aioobe

1
@alf một số hệ thống không có đồng hồ chính xác đến từng mili giây có thể loại trừ một số tùy chọn nếugcd(array.length,clockAccuracy)!=1
ratchet freak

3
Tôi vừa nhận thấy một thông báo rằng tôi đã từ chối câu trả lời này - chắc hẳn tôi đã vô tình nhấp vào nó; Rất tiếc, giao diện sẽ không cho phép tôi hoàn tác (nó cho biết tôi không thể thay đổi phiếu bầu của mình trừ khi câu trả lời được chỉnh sửa ...). Vì vậy, xin gửi lời xin lỗi đến Chris Dennett.
Peter Hanley

13

Bạn có thể sử dụng Trình tạo ngẫu nhiên để tạo chỉ mục ngẫu nhiên và trả về phần tử tại chỉ mục đó:

//initialization
Random generator = new Random();
int randomIndex = generator.nextInt(myArray.length);
return myArray[randomIndex];

9

Nếu bạn định nhận một phần tử ngẫu nhiên nhiều lần, bạn muốn đảm bảo rằng trình tạo số ngẫu nhiên của bạn chỉ được khởi tạo một lần.

import java.util.Random;

public class RandArray {
    private int[] items = new int[]{1,2,3};

    private Random rand = new Random();

    public int getRandArrayElement(){
        return items[rand.nextInt(items.length)];
    }
}

Nếu bạn đang chọn các phần tử mảng ngẫu nhiên cần không thể đoán trước, bạn nên sử dụng java.security.SecureRandom thay vì Ngẫu nhiên. Điều đó đảm bảo rằng nếu ai đó biết vài lần chọn cuối cùng, họ sẽ không có lợi thế trong việc đoán lựa chọn tiếp theo.

Nếu bạn đang muốn chọn một số ngẫu nhiên từ một mảng Đối tượng bằng cách sử dụng số liệu chung, bạn có thể xác định một phương pháp để làm như vậy (Nguồn Avinash R trong Phần tử ngẫu nhiên từ mảng chuỗi ):

import java.util.Random;

public class RandArray {
    private static Random rand = new Random();

    private static <T> T randomFrom(T... items) { 
         return items[rand.nextInt(items.length)]; 
    }
}

3

sử dụng java.util.Randomđể tạo một số ngẫu nhiên giữa 0 và độ dài mảng:, random_numbervà sau đó sử dụng số ngẫu nhiên để nhận số nguyên:array[random_number]



2

Bạn cũng có thể dùng

public static int getRandom(int[] array) {
    int rnd = (int)(Math.random()*array.length);
    return array[rnd];
}

Math.random()trả về giá trị doublegiữa 0.0(bao gồm) đến 1.0(độc quyền)

Nhân giá trị này với array.lengthsẽ cho bạn một giá trị doublegiữa 0.0(bao gồm) và array.length(độc quyền)

Truyền tới intsẽ làm tròn xuống cung cấp cho bạn và số nguyên giữa 0(bao gồm) và array.length-1(bao gồm)


Math.random () trả về một double chứ không phải một int. Nếu có thì sẽ chỉ có hai giá trị khả dĩ là 0 và 1.
Akshay R.

1

Vì bạn có java 8, một giải pháp khác là sử dụng Stream API.

new Random().ints(1, 500).limit(500).forEach(p -> System.out.println(list[p]));

Trong đó 1int thấp nhất được tạo (bao gồm) và 500là cao nhất (độc quyền). limitnghĩa là luồng của bạn sẽ có độ dài là 500.

 int[] list = new int[] {1,2,3,4,5,6};
 new Random().ints(0, list.length).limit(10).forEach(p -> System.out.println(list[p])); 

Ngẫu nhiên là từ java.utilgói.



0

Java có một lớp Ngẫu nhiên trong gói java.util. Sử dụng nó, bạn có thể làm như sau:

Random rnd = new Random();
int randomNumberFromArray = array[rnd.nextInt(3)];

Hi vọng điêu nay co ich!


0
package workouts;

import java.util.Random;

/**
 *
 * @author Muthu
 */
public class RandomGenerator {
    public static void main(String[] args) {
     for(int i=0;i<5;i++){
         rndFunc();
     } 
    }
     public static void rndFunc(){
           int[]a= new int[]{1,2,3};
           Random rnd= new Random();
           System.out.println(a[rnd.nextInt(a.length)]);
       }
}

0

Bạn cũng có thể thử cách tiếp cận này ..

public static <E> E[] pickRandom_(int n,E ...item) {
        List<E> copy = Arrays.asList(item);
        Collections.shuffle(copy);
        if (copy.size() > n) {
            return (E[]) copy.subList(0, n).toArray();
        } else {
            return (E[]) copy.toArray();
        }

    }

Vì vậy, bạn xáo trộn một danh sách với O(nlogn)độ phức tạp về thời gian, tạo bản sao của nó hai lần bằng cách sử dụng tổng bộ nhớ gấp 3 lần mảng ban đầu, mặc dù vấn đề mà OP hỏi có thể được giải quyết với O(1)độ phức tạp về thời gian và O(1)bộ nhớ ...?
Jaroslaw Pawlak

vâng, bạn đúng, Tốt hơn là làm với sự phức tạp về thời gian và không gian liên tục.
Ravi Sapariya

0
package io.github.baijifeilong.tmp;

import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Stream;

/**
 * Created by BaiJiFeiLong@gmail.com at 2019/1/3 下午7:34
 */
public class Bar {
    public static void main(String[] args) {
        Stream.generate(() -> null).limit(10).forEach($ -> {
            System.out.println(new String[]{"hello", "world"}[ThreadLocalRandom.current().nextInt(2)]);
        });
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.