简体   繁体   中英

Get a non-prime number and its factors below a given maximum

I need to randomly pick a non-prime number below a given maximum, and return all its factors.

I already have all the non-primes and their factors stored in a Map<Integer, Integer[]> that is calculated once on startup.

Here's an idea of the implementation:

public Pair<Integer, Integer[]> getNonPrimeAndFactors(int maximum)
{
    //Randomly select a non-prime less than maximum
    return new Pair<Integer, Integer[]>(nonPrime, factors.get(nonPrime));
}

I'm not really sure what data structure to use in order to pick a key in that Map randomly whilst still being less than maximum . Picking a random number less than maximum, then iterating down calling factors.hasKey(randomNumber--) would be a bit crap.

I'm using Java 7 and Guava, so have Google's collections to pick from.

You can get a random key less than the maximum by converting the key set to a SortedSet and keep the head set below the maximum value.

When you have such a set, it is then possible to convert it to a list and get a random element by index:

public Pair<Integer, Integer[]> getNonPrimeAndFactors(int maximum) {
    SortedSet<Integer> set = new TreeSet<>(factors.keySet()).headSet(maximum);
    List<Integer> keys = new ArrayList<>(set);
    Integer nonPrime = keys.get(ThreadLocalRandom.current().nextInt(keys.size()));
    return new Pair<Integer, Integer[]>(nonPrime, factors.get(nonPrime));
}

generate a random number below max, check if it is a non-prime by looking into the table. If it is a prime restart from the beginning, ie generate a new random number.

Since the non-primes are much more frequent than the primes this procedure will not take long.

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