简体   繁体   中英

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 ?

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:

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!

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...

Then you have to instantiate the RandomTouples class and call the generating method to get a new tuple. 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() + ")");
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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