Error checking duplicate user-input array values - java

I am self-learning Java and am stuck on a simple project. I'd like to receive 6 unique 'lottery' numbers from a user.
User will be asked to input an integer.
Each user input will be placed into an array.
If the user inputs a previously input number, I want to prompt to reenter the number again.
Recheck the new input. If unique, continue the for loop. If non-unique, run step 3 again.
So far, all I have is:
public static int[] userLottoInput()
{
int[] userNums = new int[6];
Scanner keyboard = new Scanner(System.in);
for (int i = 0; i < userNums.length; i++ ) {
System.out.printf("Enter Lottery number %d: ", i + 1);
userNums[i] = keyboard.nextInt();
for (int k=i; k<userNums.length; k++) {
while (k!=i && userNums[k] == userNums[i]) {
System.out.printf("if");
System.out.printf("Error! Try again: ");
userNums[i] = keyboard.nextInt();
}
}
}
}
Any help is appreciated!!

Try and keep you logic simple.
While the user hasn't enter 6 numbers, loop
Ask the user for a value
Check to see if it's a duplicate
If it is, ask the user to re-enter the value
If it's not (a duplicate) increment the counter to the next element...
For example...
public static int[] userLottoInput() {
int[] userNums = new int[6];
Scanner keyboard = new Scanner(System.in);
int i = 0;
// Keep looping until we fill the array, but
// allow the control to fall somewhere else
while (i < userNums.length) {
System.out.printf("Enter Lottery number %d: ", i + 1);
userNums[i] = keyboard.nextInt();
// Check for duplicates
boolean duplicate = false;
// We only need to check up to i - 1, as all the
// other values are defaulted to 0
// We also don't need to check for the last number entered ;)
for (int k = 0; k < i; k++) {
// Check for duplicated
if (userNums[k] == userNums[i]) {
System.out.println("No duplicates allowed, please try again");
duplicate = true;
// Break out of the loop as we don't need to check any more..
break;
}
}
// If no duplicates where found, update i to the next position
if (!duplicate) {
i++;
}
}
return userNums;
}
With this, there is only one point at which you prompt the user. Everything else is used to control the element position (i) to meet your requirements.
Now, I'm sure that there are other ways to do this and this is just a simple example ;)

Move the asking of number outside loop, when received the number loop over the numbers array to find a match. If match found re-ask for number (outside the for loop used for finding the match), else if match not found, then add the number to array.

Don't you think your for loop is little complicated. Anyways, you can try this :
for (int k=0; k<i-1; k++) { //Start k=0 means from the first stored value
while (k!=i && userNums[k] == userNums[i]) {
System.out.printf("if");
System.out.printf("Error! Try again: ");
userNums[i] = keyboard.nextInt();
}
}

Related

Java: Display the complete set of unique values input after the user enters each new value

I need to write a code that "Display the complete set of unique values input after the user enters each new value." Such as:
The·complete·set·of·unique·values·entered·is:↵
Unique·Value·1:·is·100↵
Unique·Value·2:·is·10↵
Unique·Value·3:·is·20↵
I have attached my code below, and have the code completed, however, it seems to come across errors on my very last line to produce the last "this is the first time (user input) has been entered" & the unique value portion results of Unique Value # is (user input that's unique and stored in array). There seems to be an error in the very last System.out.println("Unique...) line.
Any help would be greatly appreciated.
import java.util.Scanner;
import java.util.ArrayList;
public class DisplayUniqueValueInput {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// creating an ArrayList from user input
ArrayList<Integer> userInputs = new ArrayList<Integer>(5);
// prompt user and store input
int count = 0;
while (true) {
int a = 0;
while(true) {
System.out.print("Enter an integer between 10 and 100:");
a = Integer.parseInt(sc.nextLine());
if (a < 10 || a > 100)
System.out.println("Invalid input\n");
else
break;
}
count++;
if (count == 5)
break;
boolean ifExists = false;
for(int i = 0; i<userInputs.size(); i++) {
if (userInputs.get(i) == a) {
ifExists = true;
break;
}
}
if (!ifExists){
System.out.printf("This is the first time %d has been entered\n", a);
userInputs.add(a);
}
} // end while statement
// output unique values
System.out.println("\nThe complete set of unique values entered is:\n");
for(int i = 0; i < 5; i++) {
System.out.println("Unique Value" + userInputs[i] + "is:" + " ");
}
} // end main method
} // end of class
A little off-topic but if you must store unique elements, you normally go for a Set. That being said, in the portion of the code where you collect the user input, you are asking for 5 numbers but storing 4 e.g.:
int count = 0;
while (true) {
int a = 0;
while(true) {
System.out.print("Enter an integer between 10 and 100:");
a = Integer.parseInt(sc.nextLine());
if (a < 10 || a > 100)
System.out.println("Invalid input\n");
else
break;
}
// count++;
// if (count == 5) if you break here, the code below won't be reached
// break; thus you will never store the last user input
// Lists have a method contains that does exactly what you are trying to do
// Consider using ifExists = userInput.contains(a)
boolean ifExists = false;
for(int i = 0; i<userInputs.size(); i++) {
if (userInputs.get(i) == a) {
ifExists = true;
break;
}
}
if (!ifExists){
System.out.printf("This is the first time %d has been entered\n", a);
userInputs.add(a);
}
// consider breaking here after you have collected the last user input
// alternatively, use a do{ ... } while(); loop
count++;
if (count == 5)
break;
} // end while statement
You are not printing the iteration variable i e.g.:
// output unique values
System.out.println("\nThe complete set of unique values entered is:\n");
for(int i = 0; i < userInputs.size(); i++) {
System.out.println("Unique Value " + (i + 1) + ": is " + userInputs.get(i));
}
Also as mentioned in another answer, in your for-loop the variable i must go up to < userInputs.size() since if you try to go up to 5, it will break if the user entered duplicate values.
For the last loop, you should do this instead, because your array is to store unique numbers, right? So if there is less than 5 unique number, your program will break, and why don't use Set instead?
// output unique values
System.out.println("\nThe complete set of unique values entered is:\n");
for(int i = 0; i < userInputs.size(); i++) {
System.out.println("Unique Value" + userInputs.get(i) + "is:" + " ");
}
Your error is because in the last for loop you try to access your list with userInputs[i] instead of userInputs.get(i)
If you want to accept and print only unique value, Perhaps use Set instead of ArrayList. Example:-
public static void main(String args[]){
Set<Integer> numbers = new HashSet<>();
for(String input : args){
Integer num = Integer.parseInt(input);
if(!(numbers.add(num))){
throw new IllegalArgumentException("Number already have");
}
System.out.println("Unique number =" + num);
}
}
A Set is a collection that contains no duplicate elements. Refer to its javadoc for details.
** Sample above just for brevity, you may retrofit your program with Set type.

How to check if an int contains a letter

I am trying to validate my code by error checking. I want to make sure the integer people enter does not contain a letter or more.
Here is my code. I am supposed to solve this problem using a one dimensional array. I got the code working but I am having problems with adding the error checking in.
Any help would be appreciated. Thanks
public void getNumbers() {
Scanner keyboard = new Scanner(System.in);
int array[] = new int[5];
int count = 0;
int entered = 0;
int k = -1;
while (entered < array.length) {
System.out.print("Enter a number ");
int number = keyboard.nextInt();
if (10 <= number && number <= 100) {
boolean containsNumber = false;
entered++;
for (int i = 0; i < count; i++) {
if (number == array[i]) // i Or j
{
containsNumber = true;
}
}
if (!containsNumber) {
array[count] = number;
count++;
} else {
System.out.println(number + " has already been entered");
}
} else {
System.out.println("number must be between 10 and 100");
}
//what does %d do?
for (int j = 0; j < count; j++) {
System.out.printf("%d ", array[j]);
}
System.out.println();
}
}
}
I'm assuming that you would want your program to ask the user to re-enter a number if they do not input a number the first time. In this scenario you might want to try something along the lines of this:
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number: ");
while(!sc.hasNextInt()) {
//print some error statement
sc.nextLine();
}
int number = sc.nextInt();
System.out.println("Number is: " + number); // to show the value of number
// continue using number however you wish
Since hasNextInt() returns a boolean determining whether or not the input is an Integer, the program will never leave the while-loop until the program can confirm that the user has entered an integer.
keyboard.nextInt() will throw a InputMismatchException if you input a String.
If you want to check whether Scanner has an integer to read, you can use keyboard.hasNextInt().
Alternatively, you can read the input as
String s = keyboard.next() which will take the input as a String, and then use s.matches(".*\\d+.*") to detect whether or not it is an integer.
UPDATE: To answer questions -
keyboard.hasNextInt() will return a boolean. So for example, after System.out.print("Enter a number"), you could have an if statement checking to see if keyboard can receive numerical input, ie. if(keyboard.hasNextInt). If this is true, that means the user has entered numerical input, and you could continue with sayingint number = keyboard.nextInt(). If it is false, you would know that the user input is non-numerical.

Why can't I have a user prompted varaible be the array size?

public class Sort {
public static void main(String[] args) {
int i = 1;
Scanner input = new Scanner(System.in);
// prompts the user to get how many numbers need to be sorted
System.out.print("Please enter the number of data points: ");
int data = input.nextInt();
// this creates the new array and data sets how large it is
int [] userArray = new int[data];
// this clarifies that the value is above 0 or else it will not run
if (data < 0) {
System.out.println("The number should be positive. Exiting.");
}
// once a value over 0 is in, the loop will start to get in all user data
else {
System.out.println("Enter the data:");
}
while (i <= data) {
int userInput = input.nextInt();
userArray[i] = userInput;
i++;
}
// this calls the sortArray method to sort the values entered
sortArray(userArray);
// this will print the sorted array
System.out.println(Arrays.toString(userArray));
}
}
I have set the array size equal to what the user inputs for how many variables they will be entering to be sorted. For some reason, Java only wants a set number instead of the number that is entered by the user. Is there a way to make this work?
First of all, there are a few mistakes in your code. You are checking if(data < 0) after you create your array with int[] userArray = new int[data];. You should check it before.
Furthermore, you will get ArrayIndexOutOfBoundsException because userArray[data] does not exist. Array indices start at 0, so the last index is data-1. You need to change your while-loop to while(i < data) instead of while(i <= data).
The problem is not that you have data instead of 10 as the length of the array. The problem is as I stated above: your while-loop.
Your issue is the while loop. Because arrays are 0 based and you need to only check if i < data. By setting it to <=, you are exceeding the array length and generating and ArrayIndexOutOfBoundsException
while (i < data) {
int userInput = input.nextInt();
userArray[i] = userInput;
i++;
}
You are over-indexing the array. A more standard way for inputting the data would be
for ( int i=0; i < data; i++ ) {
userArray[i] = input.nextInt();
}

How to make a functioning to do list in java

I am trying to make a functioning to do list with a limit of 10 elements, however I am having an issue with two major things in the to do list.
The first is that after I first compile and run the program and select to add elements to the list, that functions properly, but if I add two elements and the 'stop' sentinel, when I select the next option to print the to do list, I am presented with a list, showing my two elements and then the stop sentinel along with 7 null values in the list. So the first issue I am having is to get rid of the null values, I attempted using a counter as you can see in my code however that was not proving to be effective.
The next issue that I am having is that I am trying to make it so that you can add to the list, so once you select to add more things to the list, the new options the user writes, rewrites over them in the array and prints out the new values and not along with the old ones. I am assuming that can be done through some sort of recursion method but I am having a hard time figuring it out.
Any help would be greatly appreciated!
Thanks!
import java.util.Scanner;
public class ToDo {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int MAX = 10;
String[] list = new String[MAX];
int choice = 0;
while (choice != 3) {
System.out.println();
System.out.println("Type 1 to add a new thing to your to do list.");
System.out.println("Type 2 to print the to do list.");
System.out.println("Type 3 to exit the program.");
System.out.print("Select an option: ");
choice = input.nextInt();
int count = 0;
if (choice == 1) {
System.out.println("Keep hitting enter after to do's, if you want to stop, type 'stop'.");
for (int i=0;i<MAX;i++) {
list[i] = input.nextLine();
if (list[i].equals("stop")) break;
count++;
}
}
if (choice == 2) {
for (int index = 0;index < list.length; index++) {
System.out.println(list[index]);
}
}
}
}
}
As I have mentioned in the comment, you can use an ArrayList instead of String[] to make your processing much easier.
But if you want to use the array itself, there are 3 minor issues with your code.
In your choice 1 for loop, start the loop from count,
for (int i=count;i<MAX;i++) {
list[i] = input.nextLine();
if (list[i].equals("stop")) break;
count++;
}
In your choice 2 for loop, end the loop before reaching count,
for (int index = 0;index < count; index++) {
System.out.println(list[index]);
}
And move your count initialization outside the while loop.
int count = 0;
But beware, if you decide to implement removing tasks, this could get complicated and using ArrayList would become much simpler.
Instead of using a fixed size array of Strings, use an ArrayList of Strings. Then you can add elements to it as you go.
Make sure to
import java.util.ArrayList;
Declaration syntax is
ArrayList<String> myList = new ArrayList<String>();
Add elements to your list with the add() method:
myList.add(input.nextLine())
You don't need that inner for loop, instead break out of the while loop of input options when you've iterated through it 10 times.
To solve your problem of "stop" being in your list, check that the input is "stop", and stop, before you attempt to add to the list.
It is better to use ArrayList but if you still want to stick to String[] then the following program will work for you:
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
final int MAX = 10;
String[] list = new String[MAX];
int choice = 0;
while (choice != 3) {
System.out.println();
System.out.println("Type 1 to add a new thing to your to do list.");
System.out.println("Type 2 to print the to do list.");
System.out.println("Type 3 to exit the program.");
System.out.print("Select an option: ");
choice = input.nextInt();
String userEnteredItem;
if (choice == 1) {
System.out.println("Keep hitting enter after to do's, if you want to stop, type 'stop'.");
for (int i=0;i<MAX;i++) {
userEnteredItem = input.nextLine();
if(!userEnteredItem.isEmpty()) {
list[i] = userEnteredItem;
if (userEnteredItem.equals("stop")) {
break;
}
count++;
} else {
i--; // Do not increase index for empty item.
}
}
}
else if (choice == 2) {
for (int index = 0;index < count; index++) {
System.out.println(list[index]);
}
}
else {
input.close();
}
}
}
It keeps track of user items in static int count and it also closes the scanner when you do not need it.

Java - No Duplicate number array

I am in the process of creating of a Lottery Program using Java via BlueJ and I am having trouble with the user inputted numbers and the number being generated by the program (up to and including 1-49), I need the numbers that are entered by the user to not be duplicate i.e. the user cannot enter 1 and 1.
I am not really sure how to get the numbers to not be duplicate i was thinking of using an Array but im not sure what type or where to begin im rather new to the whole programming thing.
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class JavaApplication8 {
public static void main(String[] args) {
Scanner user_input = new Scanner (System.in);
Scanner keyIn = new Scanner(System.in);
int[] LotteryNumbers = new int[6];
int input;
int count = 0;
System.out.print("Welcome to my lottery program which takes\nyour lottery numbers and compares\nthem to this weeks lottery numbers!");
System.out.print("\n\nPress the enter key to continue");
keyIn.nextLine();
for (int i = 0; i < LotteryNumbers.length; i++)
{
count ++;
System.out.println("Enter your five Lottery Numbers now " + count + " (must be between 1 and 49): ");
input = Integer.parseInt(user_input.next());
if (input < 1 || input > 49)
{
while (input < 1 || input > 49)
{
System.out.println("Invalid number entered! \nPlease enter lottery number (between 1 and 49) " + count);
input = Integer.parseInt(user_input.next());
if (input >= 1 || input <= 49)
{
LotteryNumbers[i] = input;
}
}
}
else
{
LotteryNumbers[i] = input;
}
}
System.out.println("Thank you for your numbers.\nThe system will now check if you have any matching numbers");
System.out.print("Press the enter key to continue");
keyIn.nextLine();
Random randNumGenerator = new Random();
StringBuilder output = new StringBuilder();
int[] ActLotteryNumbers = new int[6];
for (int j = 0; j < ActLotteryNumbers.length; j++)
{
int roll = randNumGenerator.nextInt(49);
ActLotteryNumbers[j] = roll;
}
System.out.println(Arrays.toString(ActLotteryNumbers));
int counter = 0;
for (int i = 0; i < LotteryNumbers.length; i++)
{
for (int j = 0; j < ActLotteryNumbers.length; j++)
{
if (LotteryNumbers[i] == ActLotteryNumbers [j])
{
counter ++;
System.out.println("The numbers that match up are: \n" + LotteryNumbers[i]);
}
}
}
if (counter == 0)
{
System.out.println("You had no matching numbers this week ... Try Again next week!");
}
}
}
As "fge" mentioned, use Set to add all the values that you are getting from the user.
Get the user inputs and add it to Set.
Use a Iterator to check the user entered values and generated random numbers.
Set myset = new HashSet();
myset.add(user_input1);
myset.add(user_input1);
To retrive use the iterator'
Iterator iterator = myset.iterator();
while(iterator.hasNext(){
int value= iterator.next();
if(randomValue==value)
//do your logic here
}
I am assuming this is for a school project/lab? (This is due to the JavaApplication8 class name) If that is the case, what the instructor is most likely looking for is a contains method.
For a contains method you write a method that takes an integer and checks to see if it is already in your LotteryNumbers array and returns a boolean. It would return true if it is in the array, false if it is not in it. This method would be called before inserting the number into LotteryNumbers. You could use your count variable that doesn't appear to be used anywhere else as the limit on your loop in the contains method to avoid checking uninitialized entries.
If there is no restriction on type, the set idea suggested by others works and is more efficient, it just depends on what you are supposed to be using for your requirements.
Additionally, the logic you use should most likely be applied to ActLotteryNumbers as well. If you can't have duplicates incoming, you shouldn't have duplicate values in the comparing array. Lottery isn't fair in real life, but not that unfair ;-)
First step should be checking your restrictions on this project.

Categories