Stuck on java (arrays/loops, how to single out ones that have already been called?))

Discussion in 'Mac Programming' started by Whorehay, May 4, 2009.

  1. Whorehay macrumors 6502a

    Whorehay

    Joined:
    Feb 17, 2008
    #1
    We just learned arrays the other day, so I'm a little confused.

    Assignment is to create an array of questions, and an array of answers, ask a random question using Math.random, and to compare the user-inputted answer to the answer I have provided. (then do cute congratulations you win stuff at the end, but that's easy).

    I've got all of that.. the only part I can't quite figure is out how to not ask the same question twice.

    I have a for loop from 1 to 10 (for 10 questions), and I'm putting an integer i equal to random*10.

    Example:

    Code:
     for (int counter = 1; counter <= 10; counter++)
                {
                    int i = (int) (Math.random()* 10); 
    and then I'm calling the arrays using questions and and comparing useranswer with answers.

    I guess my question is.. how would I go about storing values the values of i that have already been produced by math.random and comparing them with the newly produced math.random integer so I don't ask the same question twice?

    ..and also checking the values while having still having the for loop run 10 times (rather than wasting a loop dealing with the comparison).

    Any tips/guidance would be helpful. Thanks!
     
  2. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #2
    The easiest way would be to have an array of booleans, called, say questionAsked, that's the same length as your question array. You just set something to true when the question is asked, then you can easily tell... However, this will be inefficient.

    Another option, in pseudocode:
    Code:
    while length > 0
      get random number between 0 and length - 1, call this x
      ask the question at the xth position
      copy 0 to x to positions 0 to x in a temporary array
      copy x+1 to length - 1 to positions x to length -2 in temporary array
      assign temporary array to original array, reducing its length by 1
    
    This takes a lot of operations in memory for the copy, and other data structures would certainly make the removal easier, but doing it as described above uses nothing but arrays. System.arraycopy can do the copy for you.

    -Lee

    EDIT: Another option, which i like best would be:
    Code:
    get an array of integers from 0 to length - 1
    shuffle this using Collections.shuffle(Arrays.asList(theArray))
    loop from 0 to length - 1, loop variable i
      get the ith element of theArray, that contains the shuffled numbers from 0 to length - 1, as x
      get the xth element of original array. Ask the question at this position
    
    This has the lowest complexity in your code, and not a lot of overhead to randomly shuffle.
     
  3. writemikep macrumors newbie

    Joined:
    May 4, 2009
    #3
    If you have to ask exactly ten questions, without duplicates, you should created a collection of Integers (0 thru 9), then Collections.shuffle() them to randomize the order, like this:

    List<Integer> list = new ArrayList<Integer>(10);
    for (int i=0; i<10; i++) {
    list.add(i); // autoboxing to Integer
    }

    Collections.shuffle(list); // randomly shuffles the list of Integers

    // now they are in random order in list

    for (Integer index : list) {
    // ask question[index.intValue()], and compare to answer[index.intValue()];
    }
     
  4. Whorehay thread starter macrumors 6502a

    Whorehay

    Joined:
    Feb 17, 2008
    #4
    my question doesn't match with answer when i try to insert the shuffle. though i probably did it wrong, since we never learned that, so that's even more confusing for me. it makes more sense to shuffle, but with the way the assignment is structured, i don't think it's that great. i think she said try to insert an IF statement.. but honestly i'm stumped/frustrated.
     
  5. lee1210 macrumors 68040

    lee1210

    Joined:
    Jan 10, 2005
    Location:
    Dallas, TX
    #5
    I gave three different suggestions... i can write the pseudocode for the first, which is the easiest to implement:
    Code:
    set numasked to 0
    initialize an array called questionAsked that is length long to false
    while numasked < length
      set x to random number
      checked if questionAsked[x] is true
        if yes, loop and try again (or increment x by 1, then % by length)
          this would look like: x = (x + 1) % myArray.length;
          you still need to check if the new value of questionAsked[x] is false
        if no, ask question[x], use answer[x], set questionAsked[x] to true, increment numanswered
    

    -Lee
     
  6. Whorehay thread starter macrumors 6502a

    Whorehay

    Joined:
    Feb 17, 2008
  7. Whorehay thread starter macrumors 6502a

    Whorehay

    Joined:
    Feb 17, 2008
    #7
    thanks so much lee. i integrated the code after a while of fiddling with your psuedocode and actually writing down the code (correcting my own syntax/logical errors) on another screen for a while, and i believe it works.
     
  8. NRose8989 macrumors 6502a

    Joined:
    Feb 6, 2008
    #8
    You could set your questions[] to null if you have already asked the question.

    so

    Code:
    int randomIndex = // generate random index
    
    while (questions[randomIndex] == null)
    {
    [INDENT]//generate new index[/INDENT]
    }
    
    System.out.println(question[randomIndex]);
    question[randomIndex] = null;
    
    
    Basically if a question is asked, then set the value to null (meaning empty). then you can test if the index is empty and know that you have already asked the question.

    I hope this help but I'm still kinda confused about what your trying to accomplish with the Math.random() because you may get ArrayIndexOutOfBounds exceptions.

    take a look at the "Random" class in the API. you can create a new Random object then call one of it's method called nextInt(value). which will return a int value between 0 and the value you pass in.

    So you can say.

    Code:
    
    Random numGen = new Random()
    
    int i = numGen.nextInt(10); // this will return a value between 0 <= x < 10, so it will fall into the bounds of your array.
    
    EDIT: Sorry I just took a gander at the API and you code for Math.random()* 10 will work just fine.

    EDIT #2: So I re-read over your question again, and since your learning array right now, I'm going to assume that you haven't learned about ArrayLists or Collections yet. With that being said try this. Also this is assuming that your question corresponds to your answer.

    Code:
    import java.util.Scanner;
    
    Scanner input = new Scanner(System.in);
    
    for (int counter = 0; counter < 10; counter++)
    {[INDENT]int randomIndex = (int) (Math.random() * 10);
    while (questions[randomIndex] == null)
    {[INDENT]
    randomIndex = (int) (Math.random() * 10);[/INDENT]
    }
    
    System.out.print(question[randomIndex]);
    
    String answer = input.nextLine();
    
    if (answer.equalsIgnoreCase(answers[randomIndex])
    {[INDENT]
    System.out.println("Correct");[/INDENT]
    }
    else
    {[INDENT]
    System.out.println("Incorrect");[/INDENT]
    }
    
    questions[randomIndex] = null;
    [/INDENT]
    }
    
    
     

Share This Page