Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Java Loops & Arrays

Options
  • 14-10-2011 2:59pm
    #1
    Closed Accounts Posts: 8,866 ✭✭✭


    Hi, I'm trying to work with a 2d array and random numbers. Each number in the four 2nd dimension arrays needs to be unique, but I cant come up with an easy way to check this?

    [php]
    //for each of the lines requested
    for(int i = 0; i < lines; i++) {

    //for each number in the line
    for(int j = 0; j < 4; j++){

    //generate a random number
    int roll = diceRoller.nextInt(6) + 1;

    //here I want to check if roll is in the array, if so discard if not insert??
    linesArray[j] = roll;
    }

    }
    [/php]


Comments

  • Registered Users Posts: 2,023 ✭✭✭Colonel Panic


    Copy the data to a new array, sort array, loop through looking for duplicates.


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    Judging by your comments... assuming this is a lottery, why are you generating a random number for each line number?

    Surely, you generate 4 random numbers first, and then for each line the user enters, check each line against the 4 numbers.


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Webmonkey wrote: »
    Surely, you generate 4 random numbers first, and then for each line the user enters, check each line against the 4 numbers.
    This. OP, you must generate the lottery numbers first! The way you are generating the numbers means that they will be different for each line.


  • Registered Users Posts: 2,781 ✭✭✭amen


    the op could be trying to create quickpick


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    Yeah, just to clarify, the user selects the number of lines they want to play before anything else, and the user then picks four numbers between 1 and 10, which are then compared against each line of different numbers.

    As for my problem, I worked around it with simply adding the numbers 1-10 to an array and using Collections.shuffle to shuffle them for each new line. thanks for your responses guys.


  • Advertisement
  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    hi again! as it turns out, webmonkey was right, I misread the brief and took that there were four lines of random numbers and one line of user input, when it was the complete opposite!

    anyway, i got on fine up until now, when i'm trying to validate user input. the numbers need to be between 1 and 10 and also unique within each line, but this isn't working for me:

    [php]
    for(int i=0; i < lines; i++) {
    for(int j=0; j<4; j++) {

    while(true){
    userNums[j] = iBox.getInteger("Please enter number "+(j+1)+" for line "+(i+1)+": ");
    //myLottery.checkUnique(userNums[j]);
    if(userNums[j] >=1 && userNums[j] <= 10 && userNums[j] != userNums[0] && userNums[j] != userNums[1] && userNums[j] != userNums[2] && userNums[j] != userNums[3]){
    break;
    } else {
    mBox.show("Number must be unique and between 1 and 10!");
    continue;
    }
    }
    }
    }
    [/php]

    any thoughts? thanks

    edit: sorry, just to clarify, it's giving me the error message no matter what number I enter.


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    [php]if(userNums[j] >=1 && userNums[j] <= 10 && userNums[j] != userNums[0] && userNums[j] != userNums[1] && userNums[j] != userNums[2] && userNums[j] != userNums[3])[/php]

    You have read into [j] which will be one of the other indices's, 0,1,2,3 so this statement will always be false. You need to check everything but the number that is read in. Consider using loops to do the check and maybe a temp var.


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    of course, thanks. mind you, there's probably no easy way to add a loop within the while statement is there?


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    hint: Give a look at Arrays.asList and look at a useful method in the List class: http://download.oracle.com/javase/1.4.2/docs/api/java/util/List.html

    There's no problem adding a nested loop in the while statement but Java supplies more useful methods to you than doing this check manually.


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    I'm thinking you're talking about using the contains method, but I'm struggling with the fact that I'm checking a 2D array. Honestly I'm only in my fifth week of java, so I have programming experience but I just don't know all my options with java yet!


  • Advertisement
  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    So I spoke to the lecturer about this, because I knew if I was stuck everybody was too, a lot of people are struggling already! Turns out she wasn't aware that the unique numbers problem was included, and said not to worry about it! However, I want to know now for my own learning purposes, so can anybody tell me how it should be done? Here's my main class code, which all works as is.

    [php]
    /*
    LotteryApp.java
    */

    import java.util.Arrays;
    import java.util.ArrayList;
    import javabook.*;

    class LotteryApp {

    public static void main(String args []) {

    //declare variables
    double money;
    int lines;
    int matches;
    double winnings = 0;
    double totalWinnings = 0;
    int[] lottoNums;
    int[][] userNums;

    //declare and create objects
    MainWindow mWin = new MainWindow();
    InputBox iBox = new InputBox(mWin);
    MessageBox mBox = new MessageBox(mWin);
    LotteryNumbers myLottery = new LotteryNumbers();
    Money myMoney = new Money();
    StringBuffer messageOut = new StringBuffer();

    mBox.show("Welcome to Java Lotto!");

    money = iBox.getDouble("Please enter the amount of money you wish you use:");
    myMoney.setMoney(money);

    while(myMoney.getMoney() >= 0.5) {

    while(true){
    lines = iBox.getInteger("How many lines do you wish to play?");
    if(lines >= 0 && lines <= 4){
    break;
    } else {
    mBox.show("Must be a number between 1 and 4, or 0 to quit!");
    continue;
    }
    }

    if(lines == 0){
    mBox.show("Thanks for playing!");
    System.exit(0);
    }

    myMoney.playCharge(lines);

    userNums = new int[lines][4];

    for(int i=0; i < lines; i++) {
    for(int j=0; j<4; j++) {

    while(true){
    userNums[j] = iBox.getInteger("Please enter number "+(j+1)+" for line "+(i+1)+": ");
    //myLottery.checkUnique(userNums[j]);
    if(userNums[j] >=1 && userNums[j] <= 10){
    break;
    } else {
    mBox.show("Number must be unique and between 1 and 10!");
    continue;
    }
    }
    }
    }

    lottoNums = myLottery.generateNumbers();

    messageOut.append("===============================================\n");
    messageOut.append("===================Java Lotto===================\n");
    messageOut.append("===============================================\n");
    messageOut.append("\n\n");

    messageOut.append("Lotto Numbers:");
    for(int nums=0; nums<4; nums++) {
    messageOut.append(" "+lottoNums[nums]);
    }

    messageOut.append("\n\n");
    messageOut.append("Your numbers are: \n\n");

    for(int x=0; x<lines; x++) {

    matches = 0;
    messageOut.append("Line "+(x+1)+": ");

    for(int y=0; y<4; y++) {
    messageOut.append(userNums[x][y]);
    messageOut.append(" ");
    for(int z=0; z<4; z++){
    if(userNums[x][y] == lottoNums[z]){
    matches++;
    }
    }
    }

    messageOut.append("\n");
    winnings=myMoney.getWinnings(matches);
    messageOut.append("You matched "+matches+" numbers for \u20ac"+winnings);
    myMoney.addWinnings(winnings);
    messageOut.append("\n\n");
    totalWinnings += winnings;

    }

    messageOut.append("You won \u20ac"+totalWinnings+" this round!");
    messageOut.append("\n\n");
    messageOut.append("You have \u20ac"+myMoney.getMoney()+" remaining!");
    mBox.show(messageOut);
    messageOut=null;

    }



    }
    }
    [/php]

    Thanks!


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Adam wrote: »
    So I spoke to the lecturer about this, because I knew if I was stuck everybody was too, a lot of people are struggling already! Turns out she wasn't aware that the unique numbers problem was included, and said not to worry about it! However, I want to know now for my own learning purposes, so can anybody tell me how it should be done? Here's my main class code, which all works as is.

    [php]
    /*
    LotteryApp.java
    */

    import java.util.Arrays;
    import java.util.ArrayList;
    import javabook.*;

    class LotteryApp {

    public static void main(String args []) {

    //declare variables
    double money;
    int lines;
    int matches;
    double winnings = 0;
    double totalWinnings = 0;
    int[] lottoNums;
    int[][] userNums;

    //declare and create objects
    MainWindow mWin = new MainWindow();
    InputBox iBox = new InputBox(mWin);
    MessageBox mBox = new MessageBox(mWin);
    LotteryNumbers myLottery = new LotteryNumbers();
    Money myMoney = new Money();
    StringBuffer messageOut = new StringBuffer();

    mBox.show("Welcome to Java Lotto!");

    money = iBox.getDouble("Please enter the amount of money you wish you use:");
    myMoney.setMoney(money);

    while(myMoney.getMoney() >= 0.5) {

    while(true){
    lines = iBox.getInteger("How many lines do you wish to play?");
    if(lines >= 0 && lines <= 4){
    break;
    } else {
    mBox.show("Must be a number between 1 and 4, or 0 to quit!");
    continue;
    }
    }

    if(lines == 0){
    mBox.show("Thanks for playing!");
    System.exit(0);
    }

    myMoney.playCharge(lines);

    userNums = new int[lines][4];

    for(int i=0; i < lines; i++) {
    for(int j=0; j<4; j++) {

    while(true){
    userNums[j] = iBox.getInteger("Please enter number "+(j+1)+" for line "+(i+1)+": ");
    //myLottery.checkUnique(userNums[j]);
    if(userNums[j] >=1 && userNums[j] <= 10){
    break;
    } else {
    mBox.show("Number must be unique and between 1 and 10!");
    continue;
    }
    }
    }
    }

    lottoNums = myLottery.generateNumbers();

    messageOut.append("===============================================\n");
    messageOut.append("===================Java Lotto===================\n");
    messageOut.append("===============================================\n");
    messageOut.append("\n\n");

    messageOut.append("Lotto Numbers:");
    for(int nums=0; nums<4; nums++) {
    messageOut.append(" "+lottoNums[nums]);
    }

    messageOut.append("\n\n");
    messageOut.append("Your numbers are: \n\n");

    for(int x=0; x<lines; x++) {

    matches = 0;
    messageOut.append("Line "+(x+1)+": ");

    for(int y=0; y<4; y++) {
    messageOut.append(userNums[x][y]);
    messageOut.append(" ");
    for(int z=0; z<4; z++){
    if(userNums[x][y] == lottoNums[z]){
    matches++;
    }
    }
    }

    messageOut.append("\n");
    winnings=myMoney.getWinnings(matches);
    messageOut.append("You matched "+matches+" numbers for \u20ac"+winnings);
    myMoney.addWinnings(winnings);
    messageOut.append("\n\n");
    totalWinnings += winnings;

    }

    messageOut.append("You won \u20ac"+totalWinnings+" this round!");
    messageOut.append("\n\n");
    messageOut.append("You have \u20ac"+myMoney.getMoney()+" remaining!");
    mBox.show(messageOut);
    messageOut=null;

    }



    }
    }
    [/php]Thanks!

    How should what be done?


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    My original question was how to validate the input to be both between 1 and 10 and unique numbers within each line.


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Adam wrote: »
    My original question was how to validate the input to be both between 1 and 10 and unique numbers within each line.
    Ok.

    Lets discuss the two approaches you could take.
    The first is defensively - making sure that there can never be a situation where a number is entered into a line if it already exists.

    The second would be to enter all the numbers and check afterwards. The end result will be the same.

    Might I suggest we go with option one?


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    My thinking exactly, I was attempting to do this at the input stage where I'm checking if the number is in the correct range, but I kept getting unreachable statement errors. My logic was at input, take the value in to a temp var, iterate through the existing elements in the current line and check each element against the temp var, and if i get a hit present the dialogue again. However I couldn't get it to work! I started going down the route of using a set, and counting the elements after each input until there was four since a set will only allow unique elements, but I couldn't get that to work either! :(


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Adam wrote: »
    My thinking exactly, I was attempting to do this at the input stage where I'm checking if the number is in the correct range, but I kept getting unreachable statement errors. My logic was at input, take the value in to a temp var, iterate through the existing elements in the current line and check each element against the temp var, and if i get a hit present the dialogue again. However I couldn't get it to work! I started going down the route of using a set, and counting the elements after each input until there was four since a set will only allow unique elements, but I couldn't get that to work either! :(

    Ok. While there are many numerous data structures, interfaces and so forth in Java that will help you, they also hide the logic of what's going on. I think it's a good idea for you to do it yourself. So lets user you array.

    Let me clarify with you on what we have to do:

    + Add a number between 1-10 to list.
    + Add a second number to the list, as long as it isn't the first.
    + Add a third number to the list, as long as it's not the first or second .
    + Add a fourth number to the list, as long as it's not the first, second or third.
    + Move on...


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    Thanks for taking the time to help me, I think I'm closer now, but i'm getting an out of bounds exception on the array in my checkUnique method.

    [php]
    // i = the line number incrementing
    for(int i=0; i < lines; i++) {

    // j = the four elements within each i
    for(int j=0; j<4; j++) {

    while(true) {

    newNum = iBox.getInteger("Please enter a number");

    if(checkUnique(userNums, newNum, lines) == 1 && newNum > 0 && newNum < 11) {
    userNums[j] = newNum;
    break;
    } else {
    mBox.show("Number already in this line!");
    continue;
    }

    }

    }
    }
    [/php]

    checkUnique method:
    [php]
    public static int checkUnique(int[][] userNums, int newNum, int line) {

    int result = 0;

    for(int x=0; x<=userNums.length; x++){
    if(userNums[line][x] == newNum) {
    result = 0;
    } else {
    result = 1;
    }
    }

    return result;

    }
    [/php]


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Adam wrote: »
    Thanks for taking the time to help me, I think I'm closer now, but i'm getting an out of bounds exception on the array in my checkUnique method.

    [php]
    // i = the line number incrementing
    for(int i=0; i < lines; i++) {

    // j = the four elements within each i
    for(int j=0; j<4; j++) {

    while(true) {

    newNum = iBox.getInteger("Please enter a number");

    if(checkUnique(userNums, newNum, lines) == 1 && newNum > 0 && newNum < 11) {
    userNums[j] = newNum;
    break;
    } else {
    mBox.show("Number already in this line!");
    continue;
    }

    }

    }
    }
    [/php]checkUnique method:
    [php]
    public static int checkUnique(int[][] userNums, int newNum, int line) {

    int result = 0;

    for(int x=0; x<=userNums.length; x++){
    if(userNums[line][x] == newNum) {
    result = 0;
    } else {
    result = 1;
    }
    }

    return result;

    }
    [/php]

    Change this:
    for(int x=0; x<=userNums.length; x++)
    

    to this:
    for(int x=0; x<userNums.length; x++)
    


  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    Ok I did that. I also corrected the value for the line I was passing to the checkUnique method, I was passing the number of lines chosen rather than the line number the loop was currently on! So now it's almost working, except that it's letting me add one duplicate i.e. I can add 1 twice on the same line, but not a third time...

    I'm thinking the hole in my logic is in the checkUnique function, am I right in saying that this block
    for(int x=0; x<userNums.length; x++){
    
    			if(userNums[line][x] == newNum) {
    				result = 0;
    			} else {
    				result = 1;
    			}
    		}
    

    is wrong, for example if the line has three values in it, and it finds that the numbers on the same on the second loop but the numbers are different on the third loop it will return that the new number is not a match? Or does the return command cut the loop short regardless of the counter?


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Adam wrote: »
    Ok I did that. I also corrected the value for the line I was passing to the checkUnique method, I was passing the number of lines chosen rather than the line number the loop was currently on! So now it's almost working, except that it's letting me add one duplicate i.e. I can add 1 twice on the same line, but not a third time...

    I'm thinking the hole in my logic is in the checkUnique function, am I right in saying that this block
    for(int x=0; x<userNums.length; x++){
    
                if(userNums[line][x] == newNum) {
                    result = 0;
                } else {
                    result = 1;
                }
            }
    
    is wrong, for example if the line has three values in it, and it finds that the numbers on the same on the second loop but the numbers are different on the third loop it will return that the new number is not a match? Or does the return command cut the loop short regardless of the counter?
    As soon as you see that there is a duplicate, you need to stop checking.
    For example, line = {4,1,9,0} and the fourth number (newNum) is a 1.
    if(userNums[line][x] == newNum)
    

    What happens here on the second iteration? What happens on the third?


  • Advertisement
  • Closed Accounts Posts: 8,866 ✭✭✭Adam


    public static int checkUnique(int[][] userNums, int newNum, int line) {
    
    		int unique = 1;
    
    		for(int i=0; i<=userNums.length; i++) {
    			if(userNums[line][i] == newNum) unique = 0;
    		}
    
    		return unique;
    
    	}
    

    So bloody simple! :rolleyes:

    One more question: Would it be considered bad practice to set the value of unique as true until proven otherwise in the loop? Thank you for your time, I really appreciate it.


  • Registered Users Posts: 3,532 ✭✭✭Unregistered.


    Adam wrote: »
    public static int checkUnique(int[][] userNums, int newNum, int line) {
    
            int unique = 1;
    
            for(int i=0; i<=userNums.length; i++) {
                if(userNums[line][i] == newNum) unique = 0;
            }
    
            return unique;
    
        }
    
    So bloody simple! :rolleyes:

    One more question: Would it be considered bad practice to set the value of unique as true until proven otherwise in the loop? Thank you for your time, I really appreciate it.

    I don't see why not. It is clear what you are doing, so from a maintenance perspective it's fine. You can however, as you mentioned earlier, return 0 as soon as you spot a duplicate. If there are no duplicates, then you can simply return 1 after the for loop.


  • Registered Users Posts: 9,579 ✭✭✭Webmonkey


    I would consider using a do while loop as it's more suited for these kind of cases.


Advertisement