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.
Related
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.
Hi it's my first post here and I have a problem:
I have a program in which, at some point, asks the user if he wants to share the stars, and if he supposedly does, the program goes back to collecting them and after some time comes back to the question if he wants to share them again.
The problem is that, when the user comes back to that point, the program ignores whatever answer u give to it and goes to the "else answer block".
It looks like this:
"Do you want to share your stars?
yes
Please answer with yes or no"
Code:
import java.util.Random;
import java.util.Scanner;
public class App {
static Scanner skan = new Scanner(System.in);
static int starCount = 0;
static Random random = new Random();
public static void main(String[] args) {
starReaching();
}
static void starReaching() {
boolean starCollected = false;
int i = 0;
int j = random.nextInt(101);
while (i < j) {
i++;
System.out.println("Stars are out of reach");
}
if (i > j || i == j) {
starCollected = true;
}
if (starCollected == true) {
starCollector();
}
}
static void starCollector() {
System.out.println("You caught a star !");
starCount++;
if (starCount == 10) {
System.out.println("You have 10 stars ! :)");
System.out.println("Do you want to share your stars?");
String line = skan.nextLine();
if (line.equals("yes")) {
skan.reset();
starGiver();
} else if (line.equals("no")) {
wishMaker();
} else {
System.out.println("Please answer with yes or no");
System.exit(0);
}
} else {
starReaching();
}
}
static void starGiver() {
System.out.println("How many do you want to share?");
int starsToShare = skan.nextInt();
if (starsToShare < 10 || starsToShare == 10 && starsToShare > 0) {
starCount = starCount - starsToShare;
System.out.println("Stars shared !");
System.out.println("You now have " + starCount + " stars");
System.out.println("Go collect them again!");
starReaching();
} else if (starsToShare > 10) {
System.out.println("You don't have enough stars to share that much!");
starGiver();
} else {
System.out.println("That's not a valid option");
starGiver();
}
}
static void wishMaker() {
}
}
Every time you call skan.nextLine() you read a new line and advance the scanner's pointer, and this is the reason your code is failing: you're calling this too often.
Instead of
if (skan.nextLine().equals("yes")) {
skan.reset();
starGiver();
} else if (skan.nextLine().equals("no")) {
wishMaker();
} else {
do:
String line = scan.nextLine(); // read from Scanner **once** only
if (line.equals("yes")) {
skan.reset();
starGiver();
} else if (line.equals("no")) {
wishMaker();
} else {
Okay i've found the little bugger, i was using skan.nextInt without using skan.nextLine after that, thank you for the quick help, much love
I'm new to this site. I've decided to create a console base hangmaan game and I've been doing ok up till now. My current problem has me stuck.
I'm trying to make it so that if the user has input a letter and it has been marked as correct or incorrect. The program should then not let the user input that same letter again in later iterations of the while loop.
The comments should give you a better idea of what I'm talking about.
Can anyone please help me?
package hangMan2;
import java.io.IOException;
import java.util.Scanner;
public class mainClss {
public static void main(String[] args) {
int point = 0;
int numberOfLetterInWord;
// prompt user for input and store input into String word
System.out.println("Enter a word in lower case from the dictionary: ");
Scanner inputWord = new Scanner(System.in);
String word = inputWord.next();
// letters remaining in word equals the length of the word at the start
int lettersRemainingInWord = word.length();
for (int i = 0; i < 30; i++) {
System.out.println("\b");
}
// while points are above 7 (7 is when man is hung) and there's more
// than one letter remaining do all the following:
while (point > -7 && lettersRemainingInWord >= 1) {
//prompts user to input letter guess and stores in letter
System.out.print("\nEnter a letter for this " + word.length()
+ " letter word: ");
Scanner inputLetter = new Scanner(System.in);
String letter = inputLetter.next();
if (word.contains(letter)) {
System.out.println("Correct!");
point += 1;
System.out.println("Score: " + point);
lettersRemainingInWord -= 1;
//I need code here to remove the current letter from being able to be used again
if (lettersRemainingInWord > 0) {
continue;
}
else {
System.out.println("\nYou win!!!");
System.out.println("The word was: " + word);
break;
}
}
else {
System.out.println("Incorrect\n");
point -= 1;
System.out.println("Score: " + point);
//I need code here to remove the current letter from being able to be used again
if (lettersRemainingInWord > 0) {
continue;
}
else {
System.out.println("Game over! You lose!");
System.out.println("Score: " + point);
System.out.println("The word was: " + word);
break;
}
}
}
if (point <= -7) {
System.out.println("Game over! You lose!");
System.out.println("Score: " + point);
System.out.println("The word was: " + word);
}
}
}
You could test whether the letter is in a Set. If not, accept it and add it to the set. If so, then reject it.
Set<String> usedLetters = new HashSet<String>();
boolean isUsedLetter(String letter) {
if (usedLetters.contains(letter)) {
return true;
} else {
usedLetters.add(letter);
return false;
}
}
You can use an ArrayList to hold the characters that have already been typed and then check the list to see if the character is in there.
List<Character> used = new ArrayList<Character>();
char let = //letter that they inputted
if(used.contains(let)) {
//do something
}
else {
used.add(let);
}
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);
I have just recently started coding and am quite the beginner. I'm trying to make a program that simply asks the user to enter a "password", and depending on whether the password is correct; increment a counter. And, once the counter reaches 10, print out a message.
Basically what I'm trying to make is like a "clip-card", like one of those you can get at a coffee shop (you get every 10th coffee free).
So, this is what I have now. I just need to know how to make the program continue after inputting a password, and keep track of the inputs.
Ohhh and... If this is unclear, please say so and I will try to clarify.
This is what I have to far...
import java.util.Scanner;
public class Coffee {
public static void main(String [] args){
int count = 0;
String pass = "hey";
System.out.println("Enter password: ");
Scanner key = new Scanner(System.in);
String moves = key.nextLine();
if(moves.compareTo(pass) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought " + count + " coffe(s)");
}
if(count % 10 == 0 && count != 0){
System.out.println("You've got a free coffe!");
}
if(moves.compareTo(pass) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
When would your program end? The way you describe it, it could just go on forever.
If that is the case, you just enclose it in a while loop :
public static void main(String [] args) {
Scanner key;
String moves;
int count = 0;
String pass = "hey";
while(true) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
moves = key.nextLine();
if(moves.compareTo(pass) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought " + count + " coffe(s)");
}
if(count % 10 == 0 && count != 0){
System.out.println("You've got a free coffe!");
}
if(moves.compareTo(pass) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
}
But you really should have an breaking condition.
You need loop(while,do-while,or for loop) to do this kind of repeated stuff .
Sample code may help
import java.util.Scanner;
public class Coffee {
public static void main(String[] args) {
int count = 0;
String pass = "hey";
System.out.println("Enter password: ");
Scanner key = new Scanner(System.in);
String moves = key.nextLine();
boolean flag = true;
while (flag) {
if (moves.compareTo(pass) == 0) {
count++;
System.out
.println("You're one step closer to a free coffe! You have so far bought "
+ count + " coffe(s)");
}
if (count == 10 && count != 0) {
System.out.println("You've got a free coffe!");
count=0;
}
if (moves.compareTo(pass) != 0) {
System.out.println("Wrong password! Try again.\n");
}
System.out.println("Do you want to continue ..(y/n)");
String choice = key.nextLine();
if (choice.equals("n")) {
flag = false;
} else {
flag = true;
}
}
}
}
I will give you a while and do-while loop to chose from
While loop
Scanner key;
String moves;
int count = 0;
String pass = "hey";
boolean condition=true;
while(condition) {
System.out.println("Enter password: ");
key = new Scanner(System.in);
moves = key.nextLine();
if(moves.compareTo(pass) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought " + count + " coffe(s)");
if(count % 10 == 0 && count != 0){
System.out.println("You've got a free coffe!");
condition=false;
}
}
else if(moves.compareTo(pass) != 0){
System.out.println("Wrong password! Try again.\n");
}
}
Do-While loop
Scanner key;
String moves;
int count = 0;
String pass = "hey";
boolean condition=true;
do{
System.out.println("Enter password: ");
key = new Scanner(System.in);
moves = key.nextLine();
if(moves.compareTo(pass) == 0){
count++;
System.out.println("You're one step closer to a free coffe! You have so far bought " + count + " coffe(s)");
if(count % 10 == 0 && count != 0){
System.out.println("You've got a free coffe!");
condition=false;
}
}
else if(moves.compareTo(pass) != 0){
System.out.println("Wrong password! Try again.\n");
}
}while(condition);