I am taking an intro class to Java and we have a project that deals with a hangman game. I have most of the code worked out but there is a bug that I can't seem to resolve.
First, the program prompts the user for a letter and one space where they think the letter goes, then the program displays a word in a series of hyphens and, if the user makes a correct guess, the letter in the corresponding hyphen is replaced with said letter.
For testing purposes, the word has been defaulted to narrow.
So if I were to guess the letter r and for space, I were to guess index 2, the program would give me:
Guess a letter: r
Guess a space: 2
Guess: --r---
The problem I am having is that when I guess the index 3 for space and try to guess the next r, the program just gives me the same output as before.
We are not allowed to use arrays or string builder because we have not talked about them yet.
Here are my variables:
// default word for testing
String blank = "narrow";
// variables to manipulate the string
String start = "";
String end = "";
String word = "";
// variables for input and output
// input is used for the user's letter guess
String input;
// space is used for the user's index guess
String space = "";
// guess is used at the end to display the word to the user and set equal to word after
// it has been manipulated
String guess = "";
Here is the code where the string is being manipulated.
for (int i = 0; i < blank.length(); i++) {
if (i == blank.indexOf(input)) {
start = guess.substring(0, i);
end = guess.substring(i + 1);
word = start.concat(input).concat(end);
}
}
I think it has to do with the if statement, but I have tried some other things and they have not worked. Any help would be appreciated.
Thank you.
The problem with your code is that everytime the blank.indexOf(input) returns 2 everytime (indexOf returns the first occurance of 'r' which is 2)
You can change the condition to check if the character at the space that the user guessed is the contains the letter that the user guessed.
You can do this as follows:
Maintain the pattern to be printed. Make a variable for this.
update the pattern everytime the user guesses correctly.
Note: In the below code guess is the variable I am talking about which is initially set to "------" for the word "narrow"
// check if the space has the letter you guessed
if (blank.charAt(space) == input.charAt(0)) {
// if it has just update the pattern string to also contain the new letter
guess = guess.substring(0, space) + input + guess.substring (space + 1)
You can just print or return (if it is a method) the pattern string.
I think blank.indexOf(input) returns only the first occurrence index of that input character. So you need to use this indexOf(int ch, int fromIndex).
In your case, store index of last occurrence of the input char in some int variable, then use that as fromIndex.
int lastOccurrence = 0;
for (int i = 0; i < blank.length(); i++) {
if (i == blank.indexOf(input, lastOccurrence)) {
lastOccurrence = i;
start = guess.substring(0, i);
end = guess.substring(i + 1);
word = start.concat(input).concat(end);
}
}
I would write it like this:
//set up variables
Scanner keyboard = new Scanner(System.in);
String word = "narrow";
String display = "";
for (int i = 0; i < word.length(); i++) {
display = display + "-";
}
//loop until the word is guessed
while (display.contains("-")) {
//show the user flow, take input
System.out.println("Guess: " + display);
System.out.print("Guess a letter: ");
String letter = keyboard.nextLine();
System.out.print("Guess a space: ");
String spaceStr = keyboard.nextLine();
int space = Integer.parseInt(spaceStr);
//check if the guess is right
if (letter.equals(word.charAt(space) + "")) {
//modify the string shown to the user
String temp = display.substring(space + 1);
display = display.substring(0, space);
display = display + letter + temp;
}
}
The key is to have one variable that is shown to the user and one which holds the real word. When they make a correct guess, you can modify the string which is shown to the user.
indexOf(String str) returns the index within this string of the FIRST OCCURENCE of the specified substring. More of this here
Best way I would suggest to do, is to change the output ONLY if the user got it right. Hence, for every guess I would do:
if(blank.charAt(space) == input.charAt(0))
{
start = guess.substring(0, space);
end = guess.substring(space + 1);
word = start.concat(input).concat(end);
}
Related
I've searched about everywhere but I just can't find anything very concrete. I've been working on this code for awhile now but it keeps stumping me.
public static void main(String[] args) {
System.out.println(palindrome("word"));
}
public static boolean palindrome(String myPString) {
Scanner in = new Scanner(System.in);
System.out.println("Enter a word:");
String word = in.nextLine();
String reverse = "";
int startIndex = 0;
int str = word.length() -1;
while(str >= 0) {
reverse = reverse + word.charAt(i);
}
}
There's a lot of ways to accomplish this using a while loop.
Thinking about simplicity, you can imagine how could you do this if you had a set of plastic separated character in a table in front of you.
Probably you'll think about get the second character and move it to the begin, then get the third and move to begin, and so on until reach the last one, right?
0123 1023 2103 3210
WORD -> OWRD -> ROWD -> DROW
So, you'll just need two code:
init a variable i with 1 (the first moved character)
while the value of i is smaller than total string size do
replace the string with
char at i plus
substring from 0 to i plus
substring from i+1 to end
increment i
print the string
The process should be:
o + w + rd
r + ow + d
d + row +
drow
Hope it helps
Here is an piece of code I write a while back that uses almost the same process. Hope it helps!
String original;
String reverse = "";
System.out.print("Enter a string: ");
original = input.nextLine();
for(int x = original.length(); x > 0; x--)
{
reverse += original.charAt(x - 1);
}
System.out.println("The reversed string is " +reverse);
Piglatin translator. at the end I am trying to get the location of the first vowel. Index is set to be the location of every vowel, but with pig latin you only need the location of the first vowel. When I run the program I don't always get the location of the first vowel. it seems to give me the second number and not the first.
import java.util.Scanner;
import javax.swing.JOptionPane;
public class Assignment_4_Piglatin {
public static void main(String[] args) {
Scanner userWord = new Scanner(System.in);
System.out.println("K. Caleb Swallow");
System.out.println("Welcome to the Pig Latin Translator!");
boolean run = true;
while (run) {
System.out.println("Please enter a word(or press Q to quit):");
String firstLetter = "something";
String firstVowel = "test";
String word = userWord.next();
String vowels = "aeiou";
if (word.equals("Q")) {
System.exit(0);
}
firstLetter = Character.toString(word.charAt(0));
if (firstLetter.equals("a") || firstLetter.equals("e") || firstLetter.equals("i") || firstLetter.equals("o") || firstLetter.equals("u")) {
System.out.println(word + "way");
} else {
for (int index = 0; index < word.length(); index++) {
if (vowels.contains(String.valueOf(word.charAt(index)))) {
System.out.print(index);
String firstNumber = Integer.toString(index);
firstVowel = Character.toString(firstNumber.charAt(0));
}
}
}
System.out.println(firstVowel);
The example seems to have some redundant code in if..else condition. If you want to print the first vowels then you can do it with a simple for loop, e.g.:
String word = userWord.next().toLowerCase();
String vowels = "aeiou";
for(int i=0 ; i<word.length() ; i++){
if(vowels.contains(String.valueOf(word.charAt(i)))){
System.out.println(word.charAt(i));
break;
}
}
Please note that you need to do toLowerCase on the actual word in order for contains to work.
There are a few problems I can see off the bat, but the one that is likely causing this error is in these lines:
String firstNumber = Integer.toString(index);
firstVowel = Character.toString(firstNumber.charAt(0));
Think about what this is doing. First, you are making a String out of the index value, then you are saying that the first vowel is at the 0th index of that string.
Think of this example: hello
The program will run and assign "4" to firstNumber and firstVowel which isn't what you want.
However, if you only have one vowel, your program will "work".
What happens if you have over ten vowels? I know this isn't a realistic example, but say it happens. Your program will assign the index of the last vowel to firstNumber (say it's 15), then it will assign the first character of that to firstVowel (1). This doesn't make much sense at all, does it, especially if you don't have a vowel in index 1.
The main problem you are encountering for words less than 10 letters in length is that you are not just outputting the second number, you are outputting the last one. One way I like to deal with this is to go through the code and put in print statements where I'm not sure what a certain value is. For example, I'd put another print statement in your loop which tells you what letter you're looking at, like so:
System.out.println("LETTER: "+ String.valueOf(word.charAt(index)));
This will help you avoid confusion. The proper way to do this problem would be to use a break statement, such as in Darshan's answer. Alternatively, you could use the properties of the for loop:
firstVowel = "";
for (int index = 0; index < word.length() && firstVowel == ""; index++) {
CODE
}
Note that the second part of the for loop is a conditional statement. You already know that this can be used to cycle through the word's characters, but you can insert any logical statement there that you want. For this example, I set the default value of firstVowel to "" (setting it to null is a faux-pas, but that's another story). Then, each time the loop runs, it checks to see if the value of firstVowel has been changed, which will of course happen on the first time a vowel is run through the loop.
So in short, you need to modify the two lines at the beginning of my post and you need to find a way to break your loop when you find the first vowel. One solution has been given here, and another in Darshan Mehta's post.
public static void main(String[] args) {
Scanner userWord = new Scanner(System.in);
System.out.println("K. Caleb Swallow");
System.out.println("Welcome to the Pig Latin Translator!");
boolean run = true;
while (run) {
System.out.println("Please enter a word(or press Q to quit):");
String firstLetter = "something";
String firstVowel = "test";
String word = userWord.next();
ArrayList<Character> vowels = new ArrayList<>();
vowels.add('a');
vowels.add('e');
vowels.add('i');
vowels.add('o');
vowels.add('u');
if (word.equals("Q")) {
System.exit(0);
}
firstLetter = Character.toString(word.charAt(0));
if (firstLetter.equals("a") || firstLetter.equals("e") || firstLetter.equals("i") || firstLetter.equals("o") || firstLetter.equals("u")) {
System.out.println(word + "way");
} else {
for (int index = 0; index < word.length(); index++) {
char indchar = word.charAt(index);
if (vowels.contains(word.charAt(index))) {
System.out.println(index);
firstVowel = Character.toString(word.charAt(index));
System.out.println(firstVowel);
index = word.length();
}
}
}
}
}
This is how I would do it. I changed the vowels String to an ArrayList so you can easily check if the char in the String word with the index is a vowel and the code works absolutely fine. It returns you the index where the first vowel is and what vowel it is.
I'm a newbie in java and I was doing this exercise, to search the second word in a string, for example, if a string is "I love java" the program should return "love".
Here is my code:
import java.util.*;
// This program returns the second word of a string
public class SecondWord{
public static void main(String[]args){
Scanner in = new Scanner(System.in);
System.out.println("String: ");
String x = in.nextLine();
int pos = x.indexOf(" ");
int pos1 = x.indexOf(" ", pos);
String second = x.substring(pos, pos1);
System.out.println(second);
}
}
It compiles, but it returns nothing. What's wrong?
When you are getting the next index of " " you should increase 1 in last index.
Change this
int pos1 = x.indexOf(" ", pos);
to
int pos1 = x.indexOf(" ", pos+1);
Note
You should increase the position by 1 when taking the substring to remove extra space in starting or trim it.
String second = x.substring(pos+1, pos1);
Alternate Solution
One better way would be of doing same thing
String x = in.nextLine();
System.out.println(x.split(" ")[1]);
Split the string by " " and print the second element.
I know this thread is pretty old, but I had run into the same question. Thank you for the solution using the split method, it was very helpful. However, I noticed a comment that said that the original code, with the pos + 1 fix, would not work if you entered only two words, and I also discovered that it would not work with only one word. This made me wonder if it was possible to find the second word using this approach without any errors when there were only one or two words. Here is what I came up with:
//For keyboard input
import java.util.Scanner;
// This program returns the second word of a string
public class SecondWord {
public static void main(String[]args) {
//Creates a scanner object for keyboard input
Scanner in = new Scanner(System.in);
//Gets a string from the user
System.out.print("String: ");
String x = in.nextLine();
//If the string contains more than one word
if (x.contains(" ")) {
//Finds the position of the first space, adds one to it to find the position of the first character of the second word
int pos = x.indexOf(" ") + 1;
//Replace the first space with a different character so the program can test if it has a second space
char[] chars = x.toCharArray();
chars[pos - 1] = 'a';
x = String.valueOf(chars);
//If there is a space after the second word
if (x.contains(" ")) {
//Finds the position of the space after the second word
int pos1 = x.indexOf(" ", pos);
//Gets the second word
String second = x.substring(pos, pos1);
//Displays the second word
System.out.println(second);
//If there is not a space after the second word
} else {
//Add a space to the end
x += " ";
//Finds the position of the space after the second word
int pos1 = x.indexOf(" ", pos);
//Gets the second word
String second = x.substring(pos, pos1);
//Displays the second word
System.out.println(second);
}
}
}
}
I want to write a loop that prompts the user to input their first middle and last name, I then want to validate that input by searching for the white spaces in between each name.
Example: First Middle Last
What I'm looking for is some thing like the following.
Pseudo Code: if name contains 2 white spaces and their are less than 3 white space in name the operation has been successful other wise tell the user to re-input their first middle and last name.
How can I go about doing this?
import java.util.Scanner;
public class Example
{
public static void main(String[] args)
{
boolean isName = false;
String name = "";
int x = name.length();
Scanner input = new Scanner(System.in);
while(!isName) // Probably better to remove the while loop entirely
{
System.out.print("Please input your 'First Middle Last' name: ");
name = input.nextLine();
name.trim(); // To remove any leading or trailing white spaces
for(int i = 0; i < x; i++)
{
if(name.lastIndexOf(' ', i) == 2 && name.lastIndexOf(' ', i) < 3)
{
isName = true;
break;
}
else
System.out.print("\nEnter your name as 'First Middle Last': ");
name = input.nextLine();
name = name.trim();
System.out.print("\nInvalid input");
}
}
}
}
The above produces an infinite loop and logically I understand why.
You could split your String on one or more white space characters and check that you get three elements. Something like,
boolean isName = false;
String name = "";
Scanner input = new Scanner(System.in);
while (!isName) {
System.out.print("Please input your 'First Middle Last' name: ");
name = input.nextLine();
isName = (name.trim().split("\\s+").length == 3);
if (!isName) {
System.out.print("\nEnter your name as 'First Middle Last': ");
}
}
Here is the problem (infinite loop):
for(int i = 0; i < x; i++)
x is initialized to 0 because name.length() is 0 initially. Since the condition i<x is never satisfied, it never enters the for loop and the while loops goes on for ever.
Right before the for loop, you need to do x = name.length(). Also, as others have suggested you need to enclose the statements inside {} for the else part.
As per this link you can count white spaces with:
int numOfSpaces = s.length() - s.replaceAll(" ", "").length();
With this you can tell if you have at least 2 spaces. The link also goes over different methods of counting how many white spaces exist in a given String.
Cheers!
I need some help with a palindrome detector that I am doing for homework. I need the user to enter a statement, so more then one word, and the program needs to detect which words are a palindrome and which ones are not. However, something in my loop is going wrong in that, it will only detect the first word then blend the others after together. I'm not sure what I'm doing wrong.
import javax.swing.JOptionPane;
public class Main {
static int numpali = 0;
public static void main(String[] args) {
// ask the user to enter a statement
String statement = JOptionPane.showInputDialog("Enter a Statement");
String reverse = "";
// Array to split the sentence
String[] words = statement.split(" ");
// Run a loop to seperate the words in the statement into single Strings
for (String word : words) {
// Print out original word
System.out.println(word + "\n");
int wordlength = word.length();
// send the word to lowercase so capitals are negligible
String wordlower = word.toLowerCase();
// Run a loop that reverses each individual word to see if its a
// palindrome
for (int t = wordlength; t > 0; t--) {
reverse += wordlower.substring(t - 1, wordlength);
wordlength--;
}
System.out.println(reverse);
// show a message if the word is a palindrome or not, and add 1 to the
// total number of palindromes
if (reverse.equals(wordlower)) {
JOptionPane.showMessageDialog(null, word + " is a Palindrome!");
numpali = numpali + 1;
}
word = "";
}
System.out.println("Number of Palindromes:" + "\n" + numpali);
}
}
I've tried to explain what its doing the best I can inside the program.
You never reset the "reverse" value inside your loop. So after the first word your just adding more characters to "reverse" every iteration.
Put
reverse = "";
inside your main for loop
Reset the value of reverse to reverse=""; just like what you have done word="";