0

I am making a program where I get how many random numbers they want and the highest number they want to go up to, but when I run the code it does not give me the amount of numbers they asked for. it either gives me 1 number or none. Then it says "Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 9 at practice4.practice4.main(practice4.java:38)" in red.

double randomNum;
        int highestNumber, numsInLottery, display;
        boolean[] numberUsed;

        System.out.println("Welcome to the Lottery Number Generator!");

        System.out.println("How many numbers are in your lottery?");
        numsInLottery = TextIO.getInt();

        System.out.println("What is the highest possible number?");
        highestNumber = TextIO.getInt();


        numberUsed= new boolean [numsInLottery];

        for (int index = 0; index < numsInLottery; index++)
        {
        numberUsed [index]= false;

        while(index < highestNumber)
        {
            do
            {

                randomNum = Math.random() * highestNumber + 1;
                display = (int) randomNum ;

            } while (numberUsed [display - 1 ] ); 

        System.out.print(display + " ");
        numberUsed [display + 1] = true;

        }   
        }
        }   
        }

before I had numberUsed= new boolean [numsInLottery]; I accidentally put highestNumber where numsInLottery is. when I had that it would give me all the numbers. but now that I have changed it it does not work any more this is what I get now

Welcome to the Lottery Number Generator!
How many numbers are in your lottery?
6
What is the highest possible number?
? 30
1 Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 21
    at practice4.practice4.main(practice4.java:35)

3 Answers3

1
do
{
    randomNum = Math.random() * highestNumber + 1;
    display = (int) randomNum ;

} while (numberUsed [display - 1 ] );

In this code you are accessing some random index of array which might not even exist for example you have 25 as the random number while you have array of size 6 only so when you access numberUsed[25] you get this exception of IndexOutOfBounds

Mustahsan
  • 3,852
  • 1
  • 18
  • 34
  • I don't really know how to fix this? I know that line is a problem but how would I change this to make it work – Brittany Gradford Feb 26 '19 at 03:38
  • if you can explain what are you trying to achieve with these two nested while and do-while loops i can help you fix it – Mustahsan Feb 26 '19 at 03:40
  • I'm trying to get the random numbers up until we reach the amount of numbers the user inputs and the assign the range of numbers to pick from and make sure no numbers are the same. sorry if this isn't a lot of information, I'm still a beginner. – Brittany Gradford Feb 26 '19 at 03:52
1

In your case it seems that you need to use a boolean array to be able to validate the generated number hasn't been generated before, in that case this is the core logic you will be needing.

int[] lotteryNumbers = new int[numsInLottery];
boolean[] lotteryNumberHasBeenGenerated = new boolean[highestNumber];

for(int i=0;i<highestNumber;i++){ //none of the numbers have been generated at this point
    lotteryNumberHasBeenGenerated[i]=false;
}

for (int i = 0; i < numsInLottery; i++) {
    int random;
    do{
        random=((Double)(Math.random() * highestNumber)).intValue();
    }while(lotteryNumberHasBeenGenerated[random]);

    lotteryNumbers[i] = random;
    lotteryNumberHasBeenGenerated[random]=true; //the number is maked as generated

}

This will make the trick and the final method should look like this:

public void lottery() {

    System.out.println("Welcome to the Lottery Number Generator!");
    System.out.println("How many numbers are in your lottery?");
    int numsInLottery = TextIO.getInt();
    System.out.println("What is the highest possible number?");
    int highestNumber = TextIO.getInt();

    int[] lotteryNumbers = new int[numsInLottery];
    boolean[] lotteryNumberHasBeenGenerated = new boolean[highestNumber];

    for(int i=0;i<highestNumber;i++){ //none of the numbers have been   generated at this point
        lotteryNumberHasBeenGenerated[i]=false;
    }

    for (int i = 0; i < numsInLottery; i++) {
        int random;
        do{
            random=((Double)(Math.random() * highestNumber)).intValue();
        }while(lotteryNumberHasBeenGenerated[random]);

        lotteryNumbers[i] = random;
        lotteryNumberHasBeenGenerated[random]=true; //the number is maked as    generated

}

    System.out.println("Lottery numbers:\n" + Arrays.toString(lotteryNumbers));
}

Although if this is the case you will be missing a lot of validations :S

Also, The problem you are having in the console logs is thrown in java when you try to access a position in the array that it does not have, for example if you created an array with size 5 and you are accessing the position number 9 or with index 8 Exception. Here is an explanation of how that works

White_King
  • 748
  • 7
  • 21
  • I wish I could use a double array but my professor says we have to use a boolean array. – Brittany Gradford Feb 26 '19 at 03:54
  • The thing is that you don't need a boolean array to generate the numbers, did he specified to you what the array should be used for? or it was just a requirement for you to use it? – White_King Feb 26 '19 at 03:57
  • 1
    she says "to use a boolean array of the numbers used for this" as a requirement. – Brittany Gradford Feb 26 '19 at 04:05
  • @White_King forgive me if this is wrong but I think the OP did mention that the resulting array should have no duplicate numbers, so I am assuming the boolean array is used to check whether or not a number has already been chosen. The process should be > create boolean array (same length as `lotteryNumbers`) > generate random number (3 for example) > check if `boolean_array[3]` is `true` and regenerate number, otherwise set `boolean_area[3]` to `true` and continue. It is certainly not the best way of accomplishing such things but I know most professors do this when teaching, including mine. – Spice Feb 26 '19 at 04:08
  • I was speculating but what about using the boolean array to verify the numbers where generated @BrittanyGradford? Regarding to the definition you are proposing @Xamser7 it kinda makes sense, actually more than my speculation, is Xamster7 specification what you think your requirement ment @BrittanyGradford? – White_King Feb 26 '19 at 04:13
  • I'm guessing that is what my professor wants me to do also. – Brittany Gradford Feb 26 '19 at 04:16
  • So I would do `for (int i = 0; i < numsInLottery; i++) { do { lotteryNumbers[i] = Math.random() * highestNumber; } while (lotteryNumbersAreGenerated[lotteryNumbers[i]]); lotteryNumbersAreGenerated[lotteryNumbers[i]]=true; }` This supposedly ensures that there are no duplicate numbers. – Spice Feb 26 '19 at 04:17
  • @White_King Sorry, I don't know how to format that correctly, also I forgot to mention my mistake in the previous comment: `lotteryNumbersAreGenerated` should contain `highestNumber` elements. – Spice Feb 26 '19 at 04:19
  • sorry, but which lines should I replace that with and are there any other lines I need to take out – Brittany Gradford Feb 26 '19 at 04:21
  • @BrittanyGradford see my answer below... – Spice Feb 26 '19 at 04:35
  • @xamser7 it says that the arrays cannot be resolved. – Brittany Gradford Feb 26 '19 at 04:48
  • It took me a lot of time trying to optimize the code for the validations, it is not worth it sry, I don't think they will even ask you for that, but I should mention the algorithm have some problems when both numbers are close to one another and especially when they get lower. doesn't have negative validations and a LOT of stuff :D so I just dropped it. the simples way should work. – White_King Feb 26 '19 at 04:58
  • @BrittanyGradford I tried it and it works fine for me, did you use my exact code? I should mention that I used a fairly old version of java which I, for some reason, have not updated. I don't know if what I did should be done differently in newer versions of java, but it is rather unlikely. – Spice Feb 26 '19 at 05:03
  • @xamser7 yes I used the exact code. Do you know if there is something that I need to import? – Brittany Gradford Feb 26 '19 at 05:19
  • I noticed that both you and @White_King initialize the boolean array to false. From my understanding, primitive data types are already initialized by the JVM. Is this something that changed in newer java versions? – Spice Feb 26 '19 at 05:25
  • @BrittanyGradford are you using eclipse? It could have to do with this: https://stackoverflow.com/questions/45770661/eclipse-arrays-cannot-be-resolved?rq=1 White_King updated his code, try his – Spice Feb 26 '19 at 05:30
  • I'm guessing so @Xamser7 – Brittany Gradford Feb 26 '19 at 05:32
  • oh I am using eclipse thanks @Xamser7 – Brittany Gradford Feb 26 '19 at 05:32
  • @BrittanyGradford ok, I just realized you were talking about the `Arrays` class. I thought you were talking about the `boolean` and `int` arrays, my bad. Yes, you need to `import java.util.Arrays`. You know, you can you use the eclipse shortcut `ctrl+shift+o` to import all required classes. – Spice Feb 26 '19 at 05:42
  • 1
    Yep just did that, thank you guys so much @Xamser7 and White_King. Works perfectly now! – Brittany Gradford Feb 26 '19 at 06:04
0

Again, as I mentioned before, I am assuming your professor wants you to use a boolean array to check if a randomly generated number already exists.

One way to accomplish this is by creating an array of booleans (isLotteryNumberGenerated) where every element represents an indication of whether the index number of that element has been generated or not (For example if we generate the random number 3 we check if isLotteryNumberGenerated[3] == true, true meaning that the number 3 has already been generated (vice versa if false). Because of this, the boolean array must be of size highestNumber + 1 in order to create an index for every number that can possibly be generated (from 0 - highestNumber)

Every time you generate a random number for element i in the lotteryNumbers array you need to check if that number has already been generated for another lotteryNumbers element. In the code below, I use a do...while loop that iterates until it generates a number that has not been generated before.

Using some of White_King's code from above...

public void lottery() {

    System.out.println("How many numbers are in your lottery?");
    int numsInLottery = TextIO.getInt();
    System.out.println("What is the highest possible number?");
    int highestNumber = TextIO.getInt();

    int[] lotteryNumbers = new int[numsInLottery];
    boolean[] isLotteryNumberGenerated = new boolean[highestNumber + 1];

    for (int i = 0; i < numsInLottery; i++) { 
        do { 

            lotteryNumbers[i] = (int) (Math.random() * (highestNumber + 1)); 

        } while (isLotteryNumberGenerated[lotteryNumbers[i]]); 

        isLotteryNumberGenerated[lotteryNumbers[i]] = true; 

    }

   System.out.println("Lottery numbers:\n" + Arrays.toString(lotteryNumbers));

}
Spice
  • 216
  • 1
  • 3
  • 12