[java] 자바에서 고유 한 난수 생성

0에서 100 사이의 임의의 숫자를 얻으려고합니다.하지만 시퀀스에서 반복되지 않고 고유해야합니다. 예를 들어 5 개의 숫자를 얻었다면 82,12,53,64,32가되어야하고 82,12,53,12,32가 아니어야합니다. 저는 이것을 사용했지만 시퀀스에서 동일한 숫자를 생성합니다.

Random rand = new Random();
selected = rand.nextInt(100);



답변

  • 목록 구조 에서 범위의 각 숫자를 순차적으로 추가합니다 .
  • 셔플 하십시오.
  • 첫 번째 ‘n’을 가져옵니다.

다음은 간단한 구현입니다. 이것은 1-10 범위에서 3 개의 고유 한 난수를 인쇄합니다.

import java.util.ArrayList;
import java.util.Collections;

public class UniqueRandomNumbers {

    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<Integer>();
        for (int i=1; i<11; i++) {
            list.add(new Integer(i));
        }
        Collections.shuffle(list);
        for (int i=0; i<3; i++) {
            System.out.println(list.get(i));
        }
    }
}

Mark Byers가 현재 삭제 된 답변에서 지적했듯이 원래 접근 방식을 사용한 수정의 첫 번째 부분은 단일 Random인스턴스 만 사용하는 것 입니다.

그것이 숫자가 동일하게 만드는 원인입니다. Random예는 밀리 세컨드의 현재 시각에 의해 시드된다. 특정 시드 값의 경우 ‘random’인스턴스는 정확히 동일한 의사 난수 시퀀스를 반환합니다 .

참고 것을 public Integer​(int value)생성자는 deprecated자바 (9) 때문이다.

첫 번째 for 루프는 간단히 다음과 같이 변경할 수 있습니다.

for (int i = 1; i < 11; i++) {
  list.add(i);
}


답변

자바로 8 + 당신이 사용할 수있는 ints방법을 Random얻기 위해 IntStream다음 임의 값을 distinct하고 limit고유 한 임의의 값의 번호로 스트림을 줄일 수 있습니다.

ThreadLocalRandom.current().ints(0, 100).distinct().limit(5).forEach(System.out::println);

Random또한 필요한 경우 LongStreams 및 DoubleStreams 를 만드는 메서드도 있습니다 .

임의의 순서로 범위의 모든 숫자 (또는 많은 양)를 원하는 경우 모든 숫자를 목록에 추가하고 섞은 다음 위의 예제가 현재 구현되어 있으므로 처음 n을 취하는 것이 더 효율적일 수 있습니다. 요청 된 범위에서 난수를 생성하고 세트를 통해 전달함으로써 ( Rob Kielty의 답변 과 유사 ), 새로운 고유 번호를 생성 할 확률이 발견 될 때마다 감소하기 때문에 제한에 전달 된 양보다 더 많이 생성해야 할 수 있습니다. 다른 방법의 예는 다음과 같습니다.

List<Integer> range = IntStream.range(0, 100).boxed()
        .collect(Collectors.toCollection(ArrayList::new));
Collections.shuffle(range);
range.subList(0, 99).forEach(System.out::println);


답변

  1. 100 개의 숫자로 구성된 배열을 만든 다음 순서를 무작위로 지정합니다.
  2. 범위가 100 인 의사 난수 생성기를 고안하십시오.
  3. 100 개의 요소로 구성된 부울 배열을 만든 다음 해당 숫자를 선택할 때 요소를 true로 설정합니다. 다음 번호를 선택할 때 배열을 확인하고 배열 요소가 설정되어 있는지 다시 시도하십시오. ( long개별 비트에 액세스하기 위해 이동 및 마스크하는 위치 의 배열을 사용하여 쉽게 명확하게 부울 배열을 만들 수 있습니다 .)


답변

Collections.shuffle()100 개의 숫자를 모두 사용 하고 여기에 표시된대로 처음 5 개를 선택합니다 .


답변

이 방법은 언급 할 가치가 있다고 생각합니다.

   private static final Random RANDOM = new Random();
   /**
     * Pick n numbers between 0 (inclusive) and k (inclusive)
     * While there are very deterministic ways to do this,
     * for large k and small n, this could be easier than creating
     * an large array and sorting, i.e. k = 10,000
     */
    public Set<Integer> pickRandom(int n, int k) {
        final Set<Integer> picked = new HashSet<>();
        while (picked.size() < n) {
            picked.add(RANDOM.nextInt(k + 1));
        }
        return picked;
    }


답변

나는 Anand의 대답을 리팩터링하여 Set의 고유 속성을 사용할뿐만 아니라 세트에 set.add()대한 추가가 실패 할 때 반환되는 부울 false도 사용했습니다 .

import java.util.HashSet;
import java.util.Random;
import java.util.Set;

public class randomUniqueNumberGenerator {

    public static final int SET_SIZE_REQUIRED = 10;
    public static final int NUMBER_RANGE = 100;

    public static void main(String[] args) {
        Random random = new Random();

        Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);

        while(set.size()< SET_SIZE_REQUIRED) {
            while (set.add(random.nextInt(NUMBER_RANGE)) != true)
                ;
        }
        assert set.size() == SET_SIZE_REQUIRED;
        System.out.println(set);
    }
}


답변

나는 이것을 그렇게 만들었다.

    Random random = new Random();
    ArrayList<Integer> arrayList = new ArrayList<Integer>();

    while (arrayList.size() < 6) { // how many numbers u need - it will 6
        int a = random.nextInt(49)+1; // this will give numbers between 1 and 50.

        if (!arrayList.contains(a)) {
            arrayList.add(a);
        }
    }