简体   繁体   English

在java中生成随机数对而不重复对

[英]Generation of pair of random numbers in java without repetition of pair

I want to generate the pair of random numbers without the repetition of the pair.我想生成一对随机数而不重复该对。 How could i implement it in java ?我怎么能在java中实现它?

Random r = new Random();
int x, y;

do {
    x = r.nextInt();
    y = r.nextInt();
} while (x == y);

We need to keep track of the pairs which are already generated.我们需要跟踪已经生成的对。 Following code should do:以下代码应该做:

Random random = new Random();
Map<Integer, Integer> generated = new HashMap<Integer, Integer>();
int x,y;
do{
    x = random.nextInt();
    y = random.nextInt();
    if(!generated.containsKey(x) || generated.get(x) != y){
        generated.put(x, y);
        break;
    }
}while(true);

In case you need more than 2 numbers, this method may be more effective:如果您需要 2 个以上的数字,此方法可能更有效:

List<Integer> integers = IntStream.range(1, 10)
        .boxed()
        .collect(Collectors.toList());

Collections.shuffle(integers);

System.out.println(integers.get(0));
System.out.println(integers.get(1));

As far as I understand your question you want to generate random pairs of numbers without repeating them.据我了解您的问题,您希望生成随机数对而不重复它们。 For that we first of all need a class holding the values, as it is a pair of numbers I'll call it tuple.为此,我们首先需要一个保存值的类,因为它是一对数字,我称之为元组。

public class Tuple {
    private Integer first;
    private Integer second;

    public Tuple(int first, int second) {
        this.first = first;
        this.second = second;
    }

    public int getFirst() {
        return first;
    }

    public int getSecond() {
        return second;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Tuple tuple = (Tuple) o;
        return first.equals(tuple.first) && second.equals(tuple.second);
    }

    @Override
    public int hashCode() {
        int result = first.hashCode();
        result = 31 * result + second.hashCode();
        return result;
    }
}

Then we need a generator class to hold the highest possible Integer that can appear in a pair.然后我们需要一个生成器类来保存可以成对出现的最高整数。 Note that this number limits how many pairs are possible, as you can have touples that contain 1...n numbers as first number and for each of them again 1...n numbers as second you can return n*n tuples at most!请注意,此数字限制了可能的对数,因为您可以将包含 1...n 个数字的元组作为第一个数字,并且对于它们中的每一个再次将 1...n 个数字作为第二个数字,您最多可以返回 n*n 个元组!

public class RandomTuples {
    private final int highestInt;
    private final Set<Tuple> usedTuples = new HashSet<>();

    public RandomTuples(int highestInt) {
        this.highestInt = highestInt;
    }

    public Tuple nextTuple() {
        if (usedTuples.size() >= highestInt*highestInt) {
            throw new RuntimeException("All possible tuples were used. " +
                    "Use a higher param when instantiating RandomTuples for more!");
        }

        Random rnd = new Random();

        Tuple tuple = Stream
                .generate(() -> new Tuple(rnd.nextInt(highestInt), rnd.nextInt(highestInt)))
                .filter(filterTuple -> !usedTuples.contains(filterTuple))
                .limit(1).findFirst().get();
        usedTuples.add(tuple);
        return tuple;
    }
}

The exception is crucial here as the stream will run into a deadlock otherwise.异常在这里至关重要,否则流将陷入死锁。 It will generate new tuples trying to get at least one matching entry ( limit(1) ) while filter will then remove this entry creating an infinite loop...它将generate新的元组,试图获得至少一个匹配的条目( limit(1) ),而filter将删除该条目,从而创建一个无限循环......

Then you have to instantiate the RandomTouples class and call the generating method to get a new tuple.然后你必须实例化 RandomTouples 类并调用生成方法来获取新的元组。 When using high numbers this can run with quite bad performance as it has to try possible combinations until it finds one that has not been used yet.当使用大量数字时,这可能会以非常糟糕的性能运行,因为它必须尝试可能的组合,直到找到尚未使用的组合。

public class RandomTuplesExample {

    public static void main(String[] args) {

        RandomTuples randomTuples = new RandomTuples(10);
        for (int i = 0; i < 100; i++) {
            Tuple tuple = randomTuples.nextTuple();
            System.out.println("(" + tuple.getFirst() + ", " + tuple.getSecond() + ")");
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM