-5

I have to create a Java program which creates an array of five elements with random values between 1 and 55, these values have to be different from the previous ones in the array. I tried this way but it actually seems not to work

import java.util.Random;

public class RandomArray {
    public static void main(String args[]) {
        Random x = new Random(System.nanoTime());
        int i, y, c = 0;
        int v[] = new int[5];
        for (i = 0; i < 5; i++) {
            c++;
            v[i] = x.nextInt(56);
            for (y = 0; y < c; y++) {
                while (v[y] == v[i]||v[i] == 0) v[i] = x.nextInt(56);
            }
        }
        for (int z : v) System.out.println(z);
    }
}
Neills
  • 3
  • 2
    "*but it actually seems not to work*" - What is the problem? – Turing85 Apr 23 '18 at 15:10
  • 1
    Doesn't *seem* to work, or *demonstrably* doesn't work *in a specific and describable way*? One of these things is considerably more answerable than the other. – David Apr 23 '18 at 15:10
  • Before you ask, you should search, ok? https://stackoverflow.com/questions/5271598/java-generate-random-number-between-two-given-values – White Apr 23 '18 at 15:11
  • 1
    ` while (v[y] == v[i]||v[i] == 0) v[i] = x.nextInt(56);` this one is causing an infinite loop – Elarbi Mohamed Aymen Apr 23 '18 at 15:13
  • It doesn't print anything at all, anyway my problem isn't giving the range but having all different values in the array – Neills Apr 23 '18 at 15:14

4 Answers4

0

I skirted trying to understand what your code is or isn't doing, because I don't think it is the best approach to add 5 unique numbers to a collection in Java. That you need unique values would lend itself well to a set.

One option here would be to use a set to store your random numbers, and to keep adding numbers until the size of the set reaches 5:

Random x = new Random(System.nanoTime());
Set<Integer> rNum = new HashSet<>();

while (rNum.size() < 5) {
    rNum.add(x.nextInt(56));
}

int v[] = new int[5];
int c = 0;
for (int num : rNum) {
    v[c] = num;
    ++c;
}

Demo

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
0

The problem with your code is that you're comparing the current value with itself, hence the endless loop. This better expresses your intents:

    Random x = new Random(System.nanoTime());
    int v[] = new int[5];
    for (int i = 0; i < 5; i++) {
        v[i] = 1 + x.nextInt(55);
        for (int y = 0; y < i; y++) {
            while (v[y] == v[i])
                v[i] = 1 + x.nextInt(55);
        }
    }
    for (int z : v)
        System.out.println(z);
forty-two
  • 12,204
  • 2
  • 26
  • 36
  • OP wrote "*[...] these values have to be different from the previous **ones** in the array*". So I presume this means pairwise difference for all elements. – Turing85 Apr 23 '18 at 15:30
0

We can use the Fisher-Yates shuffle to generate a sequence of length n <= 55 that is guaranteed to be pairwise different. For this, we only need to return the last n elements from the shuffled array. But this would be a huge waste of resources: if we need only five random values, why shuffle the whole array? just shuffle the last five positions instead!

import java.util.Arrays;
import java.util.Random;

public class RandomArray {
    private static final int[] range = new int[55];
    private static final Random rng = new Random();

    static {
        for (int i = 0; i < range.length; ++i) {
            range[i] = i + 1;
        }
    }

    public static void main(String args[]) {
        for (int i = 0; i < 10; ++i) {
            System.out.println(Arrays.toString(getNRandom(5)));
        }
    }

    /* partial Fisher-Yates shuffle for the last n elements */
    public static int[] getNRandom(final int n) {
        int limit = range.length - n;
        for (int i = range.length - 1; i >= limit && i > 0; --i) {
            int swapIdx = rng.nextInt(i);
            int tmp = range[swapIdx];
            range[swapIdx] = range[i];
            range[i] = tmp;
        }
        return Arrays.copyOfRange(range, limit, range.length);
    }
}

Demo (rextester.com)

We keep using the same source array range, even if it is mixed up a little bit already. This does not change the possibility since Fisher-Yates shuffle guarantees an equally distributed array (i.e. the probability of each number to be at the ith position after a shuffle is 1/n, where n is the array size.

This algorithm has the followung properties:

  • It terminates provably. Both answers of forty-two and Tim Biegelstein are not guaranteed to terminate1.
  • It uses the minimum randomness required, i.e. it always uses only n calls to rng.nextInt(...) when a random sequence of length n is generated. If a random sequence of length range.length is required, it needs only range.length - 1 random calls.

1 Although termination is very likely for both algorithms.

Turing85
  • 18,217
  • 7
  • 33
  • 58
0

You can use this

Random x = new Random(System.nanoTime());
int i, y, c = 0;
int v[] = new int[5];
 for (i = 0; i < 5; i++) {
  c++;
  v[i] = x.nextInt(56);
  for (y = 0; y < c; y++) {
   //SOLUTION
   int aux = v[i];
   while (aux == v[y]||v[y] == 0) v[y] = x.nextInt(56);
   //
  }
}
for (int z : v) System.out.println(z);

In oter case you have a endless loop since your are comparing all the time since v[0]==v[0] is true all the time