问题
I am trying to work out how to create an input validation where it won't let you enter the same number twice as well as being inside a range of numbers and that nothing can be entered unless it's an integer. I am currently creating a lottery program and I am unsure how to do this. Any help would be much appreciated. My number range validation works but the other two validations do not. I attempted the non duplicate number validation and i'm unsure how to do the numbers only validation. Can someone show me how to structure this please.
This method is in my Player class
public void choose() {
int temp = 0;
for (int i = 0; i<6; i++) {
System.out.println("Enter enter a number between 1 & 59");
temp = keyboard.nextInt();
keyboard.nextLine();
while ((temp<1) || (temp>59)) {
System.out.println("You entered an invalid number, please enter a number between 1 and 59");
temp = keyboard.nextInt();
keyboard.nextLine();
}
if (i > 0) {
while(temp == numbers[i-1]) {
System.out.println("Please enter a different number as you have already entered this");
temp = keyboard.nextInt();
keyboard.nextLine();
}
}
numbers[i] = temp;
}
}
回答1:
Do it as follows:
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static int[] numbers = new int[6];
static Scanner keyboard = new Scanner(System.in);
public static void main(String args[]) {
// Test
choose();
System.out.println(Arrays.toString(numbers));
}
static void choose() {
int temp;
boolean valid;
for (int i = 0; i < 6; i++) {
// Check if the integer is in the range of 1 to 59
do {
valid = true;
System.out.print("Enter in an integer (from 1 to 59): ");
temp = keyboard.nextInt();
if (temp < 1 || temp > 59) {
System.out.println("Error: Invalid integer.");
valid = false;
}
for (int j = 0; j < i; j++) {
if (numbers[j] == temp) {
System.out.println("Please enter a different number as you have already entered this");
valid = false;
break;
}
}
numbers[i] = temp;
} while (!valid); // Loop back if the integer is not in the range of 1 to 100
}
}
}
A sample run:
Enter in an integer (from 1 to 59): 100
Error: Invalid integer.
Enter in an integer (from 1 to 59): -1
Error: Invalid integer.
Enter in an integer (from 1 to 59): 20
Enter in an integer (from 1 to 59): 0
Error: Invalid integer.
Enter in an integer (from 1 to 59): 4
Enter in an integer (from 1 to 59): 5
Enter in an integer (from 1 to 59): 20
Please enter a different number as you have already entered this
Enter in an integer (from 1 to 59): 25
Enter in an integer (from 1 to 59): 6
Enter in an integer (from 1 to 59): 23
[20, 4, 5, 25, 6, 23]
回答2:
For testing a value is present in the numbers array use Arrays.asList(numbers).contains(temp)
May better if you use an ArrayList for storing numbers.
回答3:
I would rewrite the method recursively to avoid multiple loops.
If you are not familiar with recursively methods it is basically a method that calls itself inside the method. By using clever parameters you can use a recursively method as a loop. For example
void loop(int index) {
if(index == 10) {
return; //End loop
}
System.out.println(index);
loop(index++);
}
by calling loop(1)
the numbers 1 to 9 will be printed.
In your case the recursively method could look something like
public void choose(int nbrOfchoices, List<Integer> taken) {
if(nbrOfChoices < 0) {
return; //Terminate the recursively loop
}
System.out.println("Enter enter a number between 1 and 59");
try {
int temp = keyboard.nextInt(); //Scanner.nextInt throws InputMismatchException if the next token does not matches the Integer regular expression
} catch(InputMismatchException e) {
System.out.println("You need to enter an integer");
choose(nbrOfChoices, taken);
return;
}
if (value < 1 || value >= 59) { //Number not in interval
System.out.println("The number " + temp + " is not between 1 and 59.");
choose(nbrOfChoices, taken);
return;
}
if (taken.contains(temp)) { //Number already taken
System.out.println("The number " + temp + " has already been entered.");
choose(nbrOfChoices, taken);
return;
}
taken.add(temp);
choose(nbrOfChoices--, taken);
}
Now you start the recursively method by calling choose(yourNumberOfchoices, yourArrayList taken). You can also easily add two additonal parameters if you want to be able to change your number interval.
回答4:
What you want to do is use recursion so you can ask them to provide input again. You can define choices instead of 6. You can define maxExclusive instead 59 (60 in this case). You can keep track of chosen as a Set of Integer values since Sets can only contain unique non-null values. At the end of each choose call we call choose again with 1 less choice remaining instead of a for loop. At the start of each method call, we check if choices is < 0, if so, we prevent execution.
public void choose(Scanner keyboard, int choices, int maxExclusive, Set<Integer> chosen) {
if (choices <= 0) {
return;
}
System.out.println("Enter enter a number between 1 & " + (maxExclusive - 1));
int value = keyboard.nextInt();
keyboard.nextLine();
if (value < 1 || value >= maxExclusive) {
System.out.println("You entered an invalid number.");
choose(keyboard, choices, maxExclusive, chosen);
return;
}
if (chosen.contains(value)) {
System.out.println("You already entered this number.");
choose(keyboard, choices, maxExclusive, chosen);
return;
}
chosen.add(value);
choose(keyboard, --choices, maxExclusive, chosen);
}
choose(new Scanner(System.in), 6, 60, new HashSet<>());
回答5:
I hope it will help , upvote if yes
import java.util.ArrayList;
import java.util.Scanner;
public class Test {
private ArrayList<String> choose() {
Scanner scanner = new Scanner(System.in);
ArrayList<String> alreadyEntered = new ArrayList<>(6); // using six because your loop indicated me that you're taking six digits
for(int i = 0 ; i < 6 ; ++i){ // ++i is more efficient than i++
System.out.println("Enter a number between 1 & 59");
String digit;
digit = scanner.nextLine().trim();
if(digit.matches("[1-5][0-9]|[0-9]" && !alreadyEntered.contains(digit))// it checks if it is a number as well as if it is in range as well if it is not already entered, to understand this learn about regular expressions
alreadyEntered.add(digit);
else {
System.out.println("Invalid input, try again");
--i;
}
}
return alreadyEntered // return or do whatever with the numbers as i am using return type in method definition i am returning
}
scanner.close();
}
using arraylist of string just to make things easy otherwise i would have to to some parsing from integer to string and string to integer
来源:https://stackoverflow.com/questions/60544576/non-duplicates-numbers-in-user-input