Matthieu Chantepie
Matthieu Chantepie

Reputation: 11

Generating an array in java from percentage

I have an issue about coding logic here. I have to generate an array of Boolean, based on percentage.

To clarify, I got a percentage 'X' (int value) and I want to generate a array of Boolean which is composed ox X percents of 1, randomly distributed. Moreover, the length of the array is constant.

For example, I I want to generate my array of Boolean, based on X=40, I would have:

[0,1,0,1,0,0,0,0,1,1,0,0,1,0,0,1,1,0,1,0]

I did not managed to find any easy solution or an existing function to generate this array. Mays someone can help me about this?

Thank you :)

Upvotes: 1

Views: 803

Answers (4)

xerx593
xerx593

Reputation: 13281

Consider a utility function, which I see handy in many use cases, like:

// Bases on {@link java.util.Random#ints(int, int)}, but "with uniqueness and limit".
static IntStream uniqueInts(int min, int max, int count, java.util.Random rnd) {
    // check parameters ... (max > min), (max - min > count), (rnd != null...)
    // call Random.ints(min, max) with distinct and limit
    return rnd.ints(min, max).distinct().limit(count);
}

, then applied to your case ...again with BitSet, because I'd hate the fact "to waste 7 bits with each boolean":

static BitSet randomBits(int total, int goodPercent, Random rand) {
    final BitSet bitSet = new BitSet(total);
    uniqueInts(0, total,  total * goodPercent / 100, rand)
        .forEach(i -> {
            bitSet.set(i);
        });
    // bitsSet.cardinality() == total * goodPercent / 100 (!)
    return bitSet;
}

..and finally (print & main methods):

static void printBits(int length, BitSet bs, PrintStream out) {
    int i = 0;
    out.append('[');
    for (; i < bs.length(); i++) {
        out.append(bs.get(i) ? '1' : '0');
    }
    // fill with zeros (according to BitSet.length() definition...
    // and provide parameter, since BitSet lacks this information).
    for (; i < length; i++) {
        out.append('0');
    }
    out.append(']');
    out.println();
}

public static void main(String[] args) {
    int total = 20;
    int goodPercent = 40;
    Random rand = new Random();
    // repeat it total times, to make a nice square
    for (int i = 0; i < total; i++) {
        BitSet test = randomBits(total, goodPercent, rand);
        printBits(total, test, System.out);
    }
}

output:

[01100011011001010000]
[01100000000101011110]
[00000101101110001001]
[01001001000110100110]
[01001110100001110000]
[00100110011100000011]
[01011100001011001000]
[00000011101101100010]
[11101000110000010010]
[01010100100011011000]
[10000101100010001101]
[00100001110010110001]
[01100000010111100001]
[10000001110101000110]
[00001010011010100011]
[01101000001110100001]
[01000100110000101101]
[00110000001010011110]
[10011011100000000011]
[01011000010111000100]

Upvotes: 0

sirandy
sirandy

Reputation: 1838

Here is an approach for you:

import java.util.Arrays;
import java.util.Collections;
import java.util.List;    

public class RandomizeArray {    

    public static void main(String args[]) {
        Boolean[] myArray = new Boolean[40];
        int xPercentage = 40;
        int ratio = myArray.length * xPercentage / 100;

        Arrays.fill(myArray, Boolean.FALSE);

        for(int i = 0; i<ratio; i++) {
            myArray[i] = true;
        }

        List<Boolean> l = Arrays.asList(myArray);
        Collections.shuffle(l);

        System.out.println(l);

    }    

}

Output:

[false, false, false, false, true, true, true, false, false, false, true, false, false, true, false, true, true, true, false, false, true, false, false, true, false, false, true, true, false, true, false, false, false, false, true, false, true, false, false, true]

[false, false, true, false, false, false, true, false, true, true, false, false, false, false, false, true, true, true, false, false, false, true, false, false, true, true, true, false, false, false, false, true, true, false, false, true, false, true, false, true]

Upvotes: 1

Thomas Fritsch
Thomas Fritsch

Reputation: 10127

You can use (Math.random() < percentage) to get false or true with the desired probabilities.

double percentage = 0.4; // use 0.0 <= percentage <= 1.0
boolean[] array = new boolean[100];
for (int i = 0; i < array.length; i++) {
    array[i] = (Math.random() < percentage);
}

Upvotes: 1

Mike Samuel
Mike Samuel

Reputation: 120526

Random shuffling of an array explains how to shuffle an array.

// Create an array.  Initially elements are zero
int[] arr = new int[n];
// Put the right number of 1's in it
double limit = n * (X / 100.0);
for (int i = 0; i < limit; ++i) {  // Assumes X <= 100
  arr[i] = 1;
}
// Randomize the order of elements.
shuffleArr(arr);

Upvotes: 1

Related Questions