Java: implement a loop with duplicate values in Array - java

My task is to enter names into an array. If the name has already been entered, the program must alert about that and offer to reenter the player under the same number.
This is my code:
public void enterNames() {
for (int i=0; i<nameOfPlayers.length; i++)
{
do
{
// isDuplicate is a Boolean initialized to false
System.out.println("CHECK": + isDuplicate);
System.out.println("Enter player " + (i+1) + ":");
nameOfPlayers[i] = in.next();
for (int k=0; k<nameOfPlayers.length; k++)
{
if (k!=i && nameOfPlayers[i].equals(nameOfPlayers[k]))
{
isDuplicate = true;
break;
}
}
} while (isDuplicate = false);
}
}
Interesting, even when I enter a duplicate value, it is caught and assigns true to isDuplicate, but when it returns to the beginning of the while loop, the value is false again ("CHECK: false").
Looks like an easy task, but I am caught...
Also, I did not want to use HashSet and wanted to use only Array.
Thanks a lot!
EDIT:
Thanks to others, I rewrote the code to the following:
public void enterNames() {
List<String> nameOfPlayersList = new ArrayList<String>();
int i = 0;
for (i=0; i<numberOfPlayers;)
{
while(true)
{
System.out.println("Enter player " + (i+1) + ":");
String input = in.next();
if(!nameOfPlayersList.contains(input))
{
nameOfPlayersList.add(input);
i++;
break;
}
System.out.println("Player " + input + " already exists, please retry");
}
}
}

Answer reformed, used List to add more and more elements without pre defined size.
changed while (isDuplicate == false); to while (!isDuplicate);
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
List<String> nameOfPlayers = new ArrayList<String>();
boolean isDuplicate = false;
int i = 0;
do {
System.out.println("Enter player " + (i + 1) + ": or Q for Quit");
String input = scanner.next();
if (!input.equalsIgnoreCase("Q")) {
if (nameOfPlayers.contains(input)) {
isDuplicate = true;
} else {
nameOfPlayers.add(input);
isDuplicate = false;
}
System.out.println("CHECK : " + isDuplicate);
} else {
break;
}
i++;
} while (!isDuplicate);
}
Enter player 1: or Q for Quit
ankur
CHECK : false
Enter player 2: or Q for Quit
singhal
CHECK : false
Enter player 3: or Q for Quit
ankur
CHECK : true

The problem you are having is because of the
} while (isDuplicate = false);
it should be (mind the double ==)
} while (isDuplicate == false);
Apart from that your code is quite inefficient. You would probably do much better with two Arrays if that is really what you want, otherwise a linked list would be best.

Your while is incorrect, this
while (isDuplicate = false);
assigns false to isDuplicate which has a side-effect of also evaluating to false. You watned something like
while (isDuplicate == false);
or the shorter
while (!isDuplicate);

Related

How to fix this algorithmic problem with Java arrays?

I have minor problem with part of the algorithm in this code. Here is a description of the task:
User types in a choice between the numbers 0,1,5 or 2.
0 ends the program,
1 prompts the user to add a name and email to the 2d array,
5 prints out all of the names and email pairs the user typed in. And
2 allows the user to search for an exact match by typing in the name and in return the program prints out the email of the name the user is looking for.
Problem is with the choice == 2 algorithm. It seems that there is a problem and it does not work properly. No matter what the user types it will always print out "Match is found!" and return the wrong email.
Any suggestions?
Here is my code:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String[][] rolodex = new String[257][2];
System.out.println("Welcome!");
int choice;
int p = 0;
String matchValue;
boolean isFound = false;
do {
System.out.println("Please select an option: ");
choice = in.nextInt();
in.nextLine();
if (choice == 1 && p < rolodex.length) {
System.out.println("What's the name?");
rolodex[p][0] = in.nextLine();
System.out.println("What's the email?");
rolodex[p][1] = in.nextLine();
p++;
} else if (choice == 5) {
for (int i = 0; i < p; i++) {
System.out.println("email: " + rolodex[i][1]);
System.out.println("name: " + rolodex[i][0]);
System.out.println("--------------------");
}
} else if (choice == 2) {
System.out.println("Type in the name of the email you want: ");
matchValue = in.nextLine();
for (int i = 0; i < p; i++) {
if (matchValue.equals(rolodex[i][0]) && !isFound) {
isFound = true;
}
if (isFound) {
System.out.println("Match Found!");
System.out.println(rolodex[i][1]);
} else {
System.out.println("Match not found!");
}
}
}
} while (choice != 0);
System.out.println("Thank you! Have a nice day!");
}
}
The initializing of the boolean variable and not re-initializing in the following repetitions was causing the problem in your code. Hence, in the block of code I am suggesting below, I have removed the boolean variable altogether. Furthermore, you could try by breaking off from the loop once the correct email match has been identified by the program.
for (int i = 0; i < p; i++) {
if (matchValue.equals(rolodex[i][0])) {
System.out.println("Match Found!");
System.out.println(rolodex[i][1]);
break;
} else if (i == (p - 1)) {
System.out.println("Match not found!");
}
}
You need to reset the value of isFound after it has been set to true. You have not done so, hence the wrong output.
if (isFound) {
System.out.println("Match Found!");
System.out.println(rolodex[i][1]);
//Add this to your code
isFound = false;
}
There is another problem with your search. You have to stop the loop once the match has been found. You have not done so.
I do suggest you try to do it on your own. You should also check #Ayyan Tahzib answer as it contains a hint on correcting this problem of your searching procedure.
If you face any problems, do comment. I will be happy to help you.

Avoiding null in an array?

I'm a novice coder and we are given a task in college to only use Arrays
(I asked the teacher and said no array lists or whatsoever, wants to do it the rough way)
its about making an array that you are able to insert, search, or delete a value in it. I figured out the most of it by searching and applying out solutions.
But they wanted an output so that if I delete THEN I search that value, it would display that the value is gone, but the problem is since that value is deleted Java places a null in there, so when the for loop cycles through all of the nulls it creates the dreaded NullPointerException error. I'm currently searching right now for solutions with these limitations but to no avail, plus my Java vocabulary and terminology is admittedly short at the moment :P
import static java.lang.System.out;
import java.util.Scanner;
public class JavaApplication
{
public static void main(String[] args)
{
Scanner kb = new Scanner(System.in);
//initialize String array x20
String[] regName = new String[20];
int regCount = 0;
int func = 0;
while (func == 0) //Main Menu Looper
{
out.println("Select function by entering its number.");
out.println("[1] Insert");
out.println("[2] Search");
out.println("[3] Delete");
out.println("[4] Exit");
out.print("Choose Operation: ");
func = kb.nextInt(); //Choose Option
out.print("======================================");
out.print("\n");
switch (func)
{
case 1: //Insertion
//set Array index start
char yesNo;
do
{
//Inserting into arrays loop
out.print("Insert student last name: ");
regName[regCount] = kb.next();
regCount++;
out.print("\n");
//Viewing loop
out.println("Student List: ");
for (int ctrl = 0; ctrl < regCount; ctrl++)
{
out.println(regName[ctrl]);
}
out.print("\n");
//Question loop
out.print("You want to insert again(Y/N):");
yesNo = kb.findWithinHorizon(".", 0).charAt(0);
if (yesNo == 'y' || yesNo == 'Y')
{
yesNo = 'y';
}
} while (yesNo == 'y');
func = 0;
break;
case 2: //Searching
out.print("Enter keyword: ");
String search = kb.next();
boolean found = false;
int searchCount = 0;
for (int ctrl = 0; ctrl < regCount; ctrl++)
{
if (regName[ctrl].equalsIgnoreCase(search)) {
found = true;
out.println(search + " has " + " a match.");
}
else
{
out.println(search + " has " + " not found.");
}
}
out.print("\n");
func = 0;
break;
case 3: //Deleting
out.print("type surname you want to delete: ");
String toDelete = kb.next();
for (int ctrl = 0; ctrl < regCount; ctrl++)
{
if (regName[ctrl].equalsIgnoreCase(toDelete)) {
regName[ctrl] = null;
out.println("Record deleted.");
}
}
out.print("\n");
func = 0;
break;
} //switch
} //while
} //main
} //class
Other answers propose checking for null. But this won't fix your problem. As the rest of your code expects no gaps in your list of students.
Try shifting the names after you delete some of them:
case 3: //Deleting
out.print("type surname you want to delete: ");
String toDelete = kb.next();
int deleted = 0;
for (int ctrl = 0; ctrl < regCount; ctrl++) {
if (regName[ctrl].equalsIgnoreCase(toDelete)) {
out.println("Record deleted.");
deleted++;
}
if(deleted > 0) {
int newCtrl = ctrl + deleted;
regName[ctrl] = (newCtrl < regCount) ? regName[newCtrl] : null;
}
}
regCount -= deleted;
out.print("\n");
func = 0;
break;
This solution assumes that your application allows duplicated entries.
Also I've found that your search operation prints <Name> has not found multiple times even if there is a match. Try changing it like this:
case 2: //Searching
out.print("Enter keyword: ");
String search = kb.next();
boolean found = false;
int searchCount = 0;
for (int ctrl = 0; ctrl < regCount; ctrl++) {
if (regName[ctrl].equalsIgnoreCase(search)) {
found = true;
out.println(search + " has a match : #" + ctrl);
break;
}
}
if(!found) {
out.println(search + " has not found.");
}
out.print("\n");
func = 0;
break;
UPDATE: deleting only first occurrence
case 3: //Deleting
out.print("type surname you want to delete: ");
String toDelete = kb.next();
int deletedIndex = -1;
for (int ctrl = 0; ctrl < regCount; ctrl++) {
if(deletedIndex >= 0) {
int newCtrl = ctrl + 1;
regName[ctrl] = (newCtrl < regCount) ? regName[newCtrl] : null;
} else if (regName[ctrl].equalsIgnoreCase(toDelete)) {
deletedIndex = ctrl;
out.println("Record deleted : #" + deletedIndex);
regCount--;
}
}
out.print("\n");
func = 0;
break;
When searching, check for null before calling equalsIgnoreCase on it.
if (regName[ctrl]!=null && regName[ctrl].equalsIgnoreCase(search)) {
found = true;
out.println(search + " has " + " a match.");
}
else
{
out.println(search + " has " + " not found.");
}
Consider Null checks whenever you code using any data structure for avoiding un-checked exceptions. So you can add the check first which executes first and if true then only proceeds further.
if (regname[ctrl] != null && regName[ctrl].equalsIgnoreCase(search)) {
Hope this helps you solve your problem!
Just do null checks: if (regName[ctrl].equalsIgnoreCase(search)) { can become if (regname[ctrl] != null && regName[ctrl].equalsIgnoreCase(search)) { and so on.
This is equivalent to:
if (regname[ctrl] != null)
{
if (regName[ctrl].equalsIgnoreCase(search))
{
...
Because of the way Java evaluates expressions the second part will only be done if the first is ok - in your case only try to use the array if the value at that index is not null)
If you want to impress your teacher break the insert search and delete into different methods.

How to do goto in Java?

I'm trying to make a game like family feud where the user gets asked a question and they have to reply 3 times so I was wondering if there was something like goto that I could use.
Question question = questions.get(new Random().nextInt(questions.size()));
System.out.println(question.getQuestion());
Scanner scanner = new Scanner(System.in);
//want to put start right here but can't
//start:
String answer = scanner.nextLine();
for (Answer a : question.getAnswers())
{
if (a.getAnswer().toLowerCase().contains(answer))
{
System.out.println(a.getAnswer() + " " + a.getPoints());
return;
//Make it go back to start right here
}
}
System.out.println("WRONG!");
//also make it go back to start right here
You don't need goto for that. The better way would be to use break and check the result after the loop:
Question question = questions.get(new Random().nextInt(questions.size()));
System.out.println(question.getQuestion());
bool success = false;
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 3 && !success; i++) {
String answer = scanner.nextLine();
for (Answer a : question.getAnswers()) {
if (a.getAnswer().toLowerCase().contains(answer)) {
System.out.println(a.getAnswer() + " " + a.getPoints());
success = true;
break;
}
}
}
if (!success) {
System.out.println("WRONG!");
}
You're overthinking this, a for loop is all you need:
Question question = questions.get(new Random().nextInt(questions.size()));
System.out.println(question.getQuestion());
Scanner scanner = new Scanner(System.in);
for (int i = 0; i < 3; i++) {
String answer = scanner.nextLine();
boolean correct = false;
for (Answer a : question.getAnswers()) {
if (a.getAnswer().toLowerCase().contains(answer)) {
System.out.println(a.getAnswer() + " " + a.getPoints());
correct = true;
break;
}
}
if (!correct) {
System.out.println("WRONG!");
}
}
goto in any language is bad practice, as it makes it difficult to follow the code. There is practically always a better way of accomplishing what you want.
Try a simple while loop around this code like so:
String answer = scanner.nextLine();
while (true)
{
for (Answer a : question.getAnswers())
{
if (a.getAnswer().toLowerCase().contains(answer))
{
System.out.println(a.getAnswer() + " " + a.getPoints());
}
else
break; // exit the loop if IF statement is false.
}
System.out.println("WRONG!");
break;
}

can't perform array validation (out of bounds) - java

I'm not too sure on what's happening here.
Code is supposed to validate an input against an array of fixed ID numbers. But everytime I purposefully enter the wrong number, it would say that "array is out of bounds".
Not too sure on what is causing the problem, maybe someone can point out my mistake?
import java.util.Scanner;
public class isValid
{
static int accNum[] = {11111, 22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999, 10101, 20202, 30303, 40404, 50505, 60606, 70707, 80808, 90909};
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
int conti = -99;
int search = 0;
do
{
System.out.print("Enter 5-digit account number you want to validate: ");
search = keyboard.nextInt();
sequentialSearch(accNum, search);
System.out.println("");
System.out.print("Enter -9 to exit program, or any other number to validate another ID: ");
conti = keyboard.nextInt();
} while (conti != -9);
}
public static void sequentialSearch(int[] array,int value)
{
int index = 0;
int element = -1;
boolean found = false;
while (!found && index < array.length)
{
if (array[index] == value)
{
found = true;
element = index;
break; //prevent index addition if value found
}
index++;
}
if (array[index] == value)
{
System.out.println("Account " + value + " is valid.");
}
else
{
System.out.println("Account " + value + " is invalid.");
}
}
}
Problem given: http://imgur.com/39caZxD
Error message: http://imgur.com/GEr95Wb
I have modified the code and it should be something like this:
import java.util.Scanner;
public class isValid
{
static int accNum[] = {11111, 22222, 33333, 44444, 55555, 66666, 77777, 88888, 99999, 10101, 20202, 30303, 40404, 50505, 60606, 70707, 80808, 90909};
public static void main(String[] args)
{
Scanner keyboard = new Scanner(System.in);
int conti = -99;
int search = 0;
do
{
System.out.print("Enter 5-digit account number you want to validate: ");
search = keyboard.nextInt();
sequentialSearch(accNum, search);
System.out.println("");
System.out.print("Enter -9 to exit program, or any other number to validate another ID: ");
conti = keyboard.nextInt();
} while (conti != -9);
}
public static void sequentialSearch(int[] array,int value)
{
int index = 0;
int element = -1;
boolean found = false;
while (!found && index < array.length)
{
if (array[index] == value)
{
found = true;
element = index;
break; //prevent index addition if value found
}
index++;
}
if (found)
{
System.out.println("Account " + value + " is valid.");
}
else
{
System.out.println("Account " + value + " is invalid.");
}
}
}
Notice the change in the if condition present after the while loop of sequentialSearch function.
Why is that? Since the index is equal to the a value that is beyond the array indexes in case the value is not present in the array.
OK, I am really sorry that my previous solution was a little bit dumb, But now what I can suggest as second way of your solution is do like this,
while (!found && index < accNum.length)
{
if (accNum[index] == value)
{
found = true;
element = index;
System.out.println("Account " + value + " is valid.");
}
else
{
System.out.println("Account " + value + " is invalid.");
break;
}
index++;
}
Description :- Your value will be matched once and prints valid message. If it didn't match the value then it will print invalid message and loop will break.

Need help fixing the while loop

Hi i was trying to create a mock database search and, though it works, whenever i enter an input that is not part of the database, it creates an Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4 on line 23. I dont know what else to do as i see no error in the code.
import java.util.*;
public class Database {
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
String[] names = new String[4];
boolean found = false;
int i = 0;
names[0] = "Thor";
names[1] = "Ben";
names[2] = "Zoe";
names[3] = "Kate";
System.out.println("Enter Player Name");
String input = scan.nextLine();
while(found != true){
if(input.equals(names[i])){
System.out.println(input + " has been found");
found = true;
} else {
i = i+1;
}
if(i == 3 && found == false){
System.out.println(input + " was not found");
}
}
}
}
You are not leaving the loop after you print that input + " was not found".
Therefore the next iteration of the loop throws ArrayIndexOutOfBoundsException.
You should leave the loop after you finish testing the entire array.
change
while(found != true){
to
while(!found && i < names.length){
Actually you can move the if statement that tests whether the input wasn't found to be after the loop :
while(!found && i < names.length) {
if(input.equals(names[i])){
System.out.println(input + " has been found");
found = true;
} else {
i = i+1;
}
}
if(!found){
System.out.println(input + " was not found");
}
An even better alternative would be to use a for loop :
for (int i = 0; i < names.length && !found; i++) {
if(input.equals(names[i])){
System.out.println(input + " has been found");
found = true;
}
}
if(!found){
System.out.println(input + " was not found");
}
if your input doesn't matches the value of i will keep on incrementing and your length of an array is 4. Obviously ArrayindexoutofException.
To avoid you need to consider the array length also.
Change your while loop to
while (found != true) {
if (input.equals(names[i])) {
System.out.println(input + " has been found");
found = true;
} else {
i = i + 1;
}
if (i == 4 && found == false) { //changed here
System.out.println(input + " was not found");
//or found == true;
break; //and here
}
}
You need to quit the loop if THIS condition is true
i == 4 && found == false
and to actually quit, you must "break" the while condition
found != true
You can do this by setting found=true (but that's not semantically correct) or add the break instruction.
Here is an alternative solution to your while loop:
while (!found && i<4)
if (input.equals(names[i++]))found = true;
System.out.println(input+(found?" has been":" was not")+" found");
You can simply change to
while(i < names.length)
and forget the additional boolean variable. Since you want to keep iterating i until you find the solution, the stop condition will be the max i. When you do find your solution, you can simply breakthe while statement:
if (input.equals(names[i])) {
System.out.println(input + " has been found");
break;
}

Categories

Resources