4

on the first iteration- I want to create a random number from 0..10

This is how I've implement it-

 int generator= (int)(Math.random() * (10));

On the first iteration I want to create another random number, but without one of the values. For example I would like the random number without the number 4. only 1,2,3,5,6,7,8,9,0

How can I remove one of the values from the numbers 0..10 when I generate a random number?

9
  • 5
    While generating random use Random.nextInt(10)==4 generate again Commented Oct 30, 2012 at 18:50
  • 4
    You can create an array holding all the values you want to be present and generate the index of the value. Commented Oct 30, 2012 at 18:51
  • 1
    @AmitD post it as an answer I'd vote up. Commented Oct 30, 2012 at 18:51
  • @AmitD That might not be the best approach, since the randomized might pick 4 several times before anything else. Commented Oct 30, 2012 at 18:55
  • @AmitD That's extremely inefficient, as TheLima points out. Commented Oct 30, 2012 at 18:56

7 Answers 7

5

1st Way: -

You can also maintain a List of all the numbers. Then use Collections.shuffle to shuffle the list and get the first element. And remove it.

    List<Integer> list = new ArrayList<Integer>();

    list.add(1); 
    list.add(4);
    list.add(2);
    list.add(3);
    System.out.println("Original List: " + list);

    Collections.shuffle(list);

    System.out.println("Shuffled List: " + list);
    int number1 = list.remove(0);  // Remove the first value
    System.out.println("Number removed: " + number1);

    Collections.shuffle(list);

    System.out.println("Shuffled List: " + list);
    number1 = list.remove(0);
    System.out.println("Number removed: " + number1);

OUTPUT: -

Original List: [1, 4, 2, 3]
Shuffled List: [4, 3, 1, 2]
Number removed: 4
Shuffled List: [1, 3, 2]
Number removed: 1

2nd Way: -

A better way would be to generate a random number from 0 to the size of the list, and get the value of that index and remove it.

int size = list.size();
Random random = new Random();

for (int i = 0; i < size; i++) {    
    int index = random.nextInt(list.size());
    int number1 = list.remove(index);
    System.out.println(number1);
}

NOTE: - If you want to exclude a fixed set of numbers from being generated, then you can have those numbers in a list. And then remove all elements of that list from your list of numbers. And then use any of the approach above.

Sign up to request clarification or add additional context in comments.

3 Comments

You are using List on a 10-elements issue and shuffling on each iteration. "Terribly inefficient" would be an understatement, no offence intended. ___ Also, the OP never really specified removal of elements in the first place. Actually, the fact he removes the 4 before the first iteration indicates he's simply wanting an exception in the randomizer's range of output values.
@TheLima. I'm not considering it a 10-elements issue. I assume that number of elements may vary. And regarding your last statement, I have added that possibility in a Note in last line. Please see it. Also, if you think this is higly in-efficient, which you have said for almost all the answers. Please post an efficient one that you know. We can learn from it.
@RohitJain - Well, a 10-element issue is what is presented by the OP. I think that for the OP's and community's best understanding and learning, the explanation and examples answered should be focused around what the OP provides, and aimed at providing the best efficiency toward that. If any change is due for the real implementation, it's the coder's responsibility, not answer's. ___ About your request: Take a better look at the answers...Seems you missed mine.
1
int generator= (int)(Math.random() * (10));
if (generator >= 4) generator++;

This will include the number 10 as a possible outcome, if you do not want this, multiply by 9 instead of 10.

4 Comments

This will no longer be psuedorandom.
there is a pseudo-2/10 chance of 5, while others have a 1/10 chance.
If and only if the first line returns 4, the second line will make it 5. If the first line returns 5, the result will be 6. 0-0, 1-1, 2-2, 3-3, 4-5, 5-6, 6-7, 7-8, 8-9, 9-10. I don't see how that's not pseudorandom. Or have I overlooked something?
hmm. No, you are right. My mistake, sorry. +1 for efficient method, unlike 6/8 so far.
1

You could store the values in a list, and generate a random index to take from that list.

private Random random = new Random();
private ArrayList<Integer> values = new ArrayList<Integer>();

public static int nextInt() {
    if (values.size() > 0) {
        return values.remove(random.nextInt(values.size()));
    } else {
        throw new RuntimeException("no values possible");
    }
}

4 Comments

Using a list instead of array for a 10-elements issue is beyond overkill.
@TheLima Probably, but the question uses the 10 elements only as an example, so I wrote my answer with wider application in mind.
Is your code supposed to return a different number each call ? that has not been asked by the OP, he only wants a random number different from 4: example 3, than 2, than 5, than 2 again, etc.. (but never 4). This might be efficient but for another question!
@jidma Refer to Rohit Jain's most recent comment on the question; he and I have both interpreted the question this way.
1

Random.nextInt(10)==number generate again

public int generateExcept(int number) {
    Random random = new Random();

    int generated = 0;
    while ((generated = random.nextInt(11)) == number) {
    }
    return generated;
}

As quoted by OP

On the first iteration I want to create another random number, but without one of the values

If I understand correctly This is single operation not repetitive operation.

Without Regeneration

public static int generateExcept(int number, int max) {
    Random random = new Random();
    int generated = 0;
    if ((generated = random.nextInt(max - 1)) == number) {
        generated++;
    }
    return generated;
}

Random is always generated max-1 because we want to increment by one

10 Comments

nextInt(11) for 0 to 10 - although it is not clear if the OP wants 10 to be included or not in the range of possible outcome...
@AmitD You can receive the exclusion value several times from random.nextInt(11). It's not so much an issue with one value excluded, but it's extremely non-scalable (in the case of excluding several values).
that was exactly my answer on which i received a -1 ... not fair.
@Vulcan The cost of creation collection and remove item from collections is always more than creation of new random int
@jidma I didn't downvote your answer, nor will I downvote this one, because it's technically correct, despite being inefficient.
|
1

There are two basic efficient approaches:

1 - Generate an array of valid values (0 to 10 except 4), and use the randomizer to pick an index on that array. An example follows:

Random random = new Random();
int[] unwanted = {4};
int[] values = new int[10-unwanted.length];
for(int i=0; i<10-unwanted.length; i++){
  for(int curr : unwanted){
    if(i == curr) continue;
  }
  values[i] = i;
}
int result = values[random.nextInt(10-unwanted.length)];

2 - Follow Simon André's approach.

5 Comments

Generate an array of valid values (0 to 10 except 4) how will you define generation except 4 its just an example from OP
I don't see how the second approach is pseudorandom at all? As I understand what you have written, that will drastically decrease the probability of the numbers 5-10. I do think the first approach is good though.
@SimonAndréForsberg - Yes, I noticed that right after posting. Fixed.
@TheLima Much better, and you're referring to my answer in your answer, definitely worth an upvote :)
@AmitD - I will pretend the question is worthy of explanation, even tough you should have figured it fairly easily. hard-coded: int[] values = {0,1,2,3,5,6,7,8,9,10} or adaptive: int[] unwanted = {4}; int[] values = new int[10-unwanted.length]; for(int i=0; i<10-unwanted.length; i++){for(int curr:unwanted){if(i==curr) continue;} values[i] = i;}
0

What you could do (perhaps there is a cleaner way of handling this) is to check the 2nd generated number to see if it matches the first, and if it does, just have it run the random num. generator again. A simple if...else loop should take care of it.

Comments

0
int excluded[] = { 1,4,3};
Random r = new Random();
int generator;
do {
    generator= r.nextInt(10);
} while (! Arrays.asList(excluded).contains(generator) )

5 Comments

see also Random.nextInt(10)
How can you exclude several numbers? like array of few numbers. for example [4,5]
This can repeat the operation several times before getting a number different from 4. -1
@TheLima i don't see how this is different from AmitD's answer
@TheLima and also, 1% chance this would repeate twice before you get something different than 4. 0.1% chance for three times.. etc..

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.