What this program does is takes words entered by the user and returns them in pig-latin form. The translation loop continues until the user enters "quit". My problem is that while the program executes and translates the words, after the word quit is entered the it translates "quit" which I don't want it to do. I know that the reason that it translates "quit" before finishing is that it's a do while loop but I'm stuck on how create a while loop that functions. How would I alter the program so that "quit" is what terminates the loop and isn't translated?
Example:
Word: quit
uit-qay
import java.util.Scanner;
public static void main(String[] args) {
String word;
Scanner input = new Scanner(System.in);
do {
System.out.print("Word: ");
word = input.next();
System.out.println(pigLatinWord(word));
System.out.println();
} while (!word.equalsIgnoreCase("quit"));
System.out.println("Translation complete");
}
// --------------------------------------------------------
// Convert one word to pig Latin.
public static String pigLatinWord(String s) {
String pigWord;
if (isVowel(s.charAt(0))) {
pigWord = s + "-way";
} else if (s.startsWith("th") || s.startsWith("Th")) { // or
// (s.toUpperCase().startsWith("TH"))
pigWord = s.substring(2) + "-" + s.substring(0, 2) + "ay";
} else {
pigWord = s.substring(1) + "-" + s.charAt(0) + "ay";
}
return pigWord;
}
// ---------------------------------------------
// Determines whether c is a vowel character
public static boolean isVowel(char c) {
String vowels = "aeiouAEIOU";
return (vowels.indexOf(c) >= 0); // when index of c in vowels is not -1,
// c is a vowel
}
}
You're executing pigLatinWord(word) before you get a chance to check if the word equals "quit". You can change the loop as such:
do {
System.out.print("Word: ");
word = input.next();
if( "quit".equalsIgnoreCase(word) )
break;
System.out.println(pigLatinWord(word));
System.out.println();
} while (true);
do {} while (); is generally bad to use, try to use while () {} instead. Like this:
Scanner input = new Scanner(System.in);
boolean shouldQuit = false;
while (!shouldQuit) {
System.out.print("Word: ");
word = input.next();
if (word.equalsIgnoreCase("quit")) {
shouldQuit = true;
} else {
System.out.println(pigLatinWord(word));
System.out.println();
}
}
System.out.println("Translation complete");
Or if you want to stick with do {} while, see the other answer.
This is one possible way. Though, it'll involve not using a do-while.
//This is an infinite loop, except that we have our exit condition inside the
//body that'll forcibly break out of the loop.
while (true) {
System.out.print("Word: ");
word = input.next();
if (word.equalsIgnoreCase("quit")) {
break; //Whelp! The user wants to quit. Break the loop NOW
}
System.out.println(pigLatinWord(word));
System.out.println();
}
System.out.println("Translation complete");
This one works, i tried it :)
String word;
Scanner input = new Scanner(System.in);
System.out.print("Word: ");
while(!(word = input.next()).equalsIgnoreCase("quit")) {
System.out.print("Word: ");
System.out.println(pigLatinWord(word));
System.out.println("fsfafa");
}
System.out.println("Translation complete");
Related
I have the following code, which continues to ask the user to enter a letter as long as the letter is either "a" or "b":
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter;
System.out.print("Enter a letter: ");
letter = scan.nextLine();
while(letter.equals("a") || letter.equals("b"))
{
System.out.println("You entered: " + letter);
System.out.print("Enter a letter: ");
letter = scan.nextLine();
}
}
}
But the following code is repeated twice:
System.out.print("Enter a letter: ");
letter = scan.nextLine();
Is there a way to make the above code only appear one time?
while (true) {
System.out.print("Enter a letter: ");
String letter = scan.nextLine();
if (!letter.equals("a") && !letter.equals("b"))
break;
System.out.println("You entered: " + letter);
}
This is the classic example of a loop that is neither naturally while-do nor do-while — it needs to exit from the middle, if you want the same behavior and also to reduce code duplication.
(Notice also that the variable declaration letter has been moved to an inner scope since it is no longer needed in the outer scope. This is a small positive indication.)
As an alternative to while (true) some languages allow degenerate for-loop as in for(;;).
The below reverses the logic of the conditional loop exit test, at the expense of more control flow logic.
while (true) {
System.out.print("Enter a letter: ");
String letter = scan.nextLine();
if (letter.equals("a") || letter.equals("b")) {
System.out.println("You entered: " + letter);
continue;
}
break;
}
(There is no difference between these in efficiency terms — these are equivalent at the level of machine code.)
do while loop
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter;
do{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
System.out.println("You entered: " + letter);
}while(letter.equals("a") || letter.equals("b"));
}
}
It will loop once first, and then continue again if the statment is true.
You need to perform three sequential actions in a loop:
read the input entered by the user;
validate the input;
print the input, but only if it is valid.
That means that conditional logic must reside inside the loop before the statement that prints the input. And that makes the condition of the loop redundant. Instead, we can create an infinite loop with a break statement wrapped by a condition, that validates the input.
While loop
That's how it can be done using a while loop:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String letter;
while (true) {
System.out.print("Enter a letter: ");
letter = scan.nextLine();
if (!letter.matches("[ab]")) break;
System.out.println("You entered: " + letter);
}
}
Method matches() that expects a regular expression as argument is used in the code above to simplify the termination condition.
For more information on regular expressions, take a look at this tutorial
For loop
Regarding the advice of utilizing a for loop - that's doable, but by its nature the task of reading the user input fits better in the concept of while loop because we don't know the amount of data in advance, and the iteration can terminate at any point in time.
Also note syntax of the for statement consists of three parts separated with a semicolon:
initialization expression - allow to define and initialize variables that would be used in the loop;
termination expression - condition which terminates the execution of the loop;
increment expression - defines how variables would change at each iteration step.
All these parts are optional, but the two semicolons ; inside the parentheses always have to be present.
Because as I've said earlier, the input needs to be validated inside the loop, we can't take advantage from the termination expression and increment expression.
For the sake of completeness, below I've provided the version of how it can be achieved using a for loop:
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
for (String letter = "a"; ;) {
System.out.print("Enter a letter: ");
letter = scan.nextLine();
if (!letter.matches("[ab]")) break;
System.out.println("You entered: " + letter);
}
}
The only advantage is that the scope of the variable letter was reduced. But approach of utilizing while loop is more readable and expressive.
Alternative approach
Another option is to preserve your initial structure of the code:
initialize the variable letter before the loop, at the same line where it is defined;
enter the loop if letter holds a valid input;
print the input and reassign the variable.
But in order to avoid duplication of the code line responsible for printing the prompt and reading the input will be extracted into a separate method.
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
String letter = readInput(scan);
while (letter.matches("[ab]")) {
System.out.println("You entered: " + letter);
letter = readInput(scan);
}
}
public static String readInput(Scanner scan) {
System.out.print("Enter a letter: ");
return scan.nextLine();
}
As Bobulous mentioned, a do-while loop is another simple solution. If duplicating the conditional is still a deal-breaker for you, though, you can also create a function that returns a boolean, and, when true, prints the extra text.
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter;
do
{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
} while(inputIsAOrB(letter));
}
public static boolean inputIsAOrB(String input) {
if (input.equals("a") || input.equals("b"))
{
System.out.println("You entered: " + input);
return true;
}
else
{
return false;
}
}
A while loop with a break after executing your second print command will limit the code to only asking for a single input.
Scanner ct = new Scanner(System.in);
String input;
System.out.print("Please enter either 'a' or 'b': ");
input = ct.nextLine();
while(input.equals("a") || input.equals("b")){
System.out.println("You entered: " + input);
break;
}
You can also view the problem as generating and processing a stream of strings. The side effects in the generator may trigger some philosophical discussions, otherwise I think it is quite clean:
Stream.generate(() -> {
System.out.print("Enter a letter: ");
return scan.nextLine();
})
.takeWhile(str -> str.equals("a") || str.equals("b"))
.forEach(str -> System.out.println("You entered: " + str));
... which will run like this:
Enter a letter: a
You entered: a
Enter a letter: b
You entered: b
Enter a letter: c
Process finished with exit code 0
Simply
List<Character> expectedChars = new ArrayList<>();
expectedChars.add('a');
expectedChars.add('b');
while(!expectedChars.contains(line = scan.nextLine())) {
System.out.println("Not expected");
}
// Now has a expected char. Proceed.
I without using any break or if-else externally (I am using ternary operator though) within control loop, you can also use below :
Scanner scanner = new Scanner(System.in);
boolean flag=true;
while (flag) {
System.out.println("enter letter");
String bv = scanner.nextLine();
flag=bv.matches("a|b");
System.out.println(flag?"you entered"+bv:' ');
}
with for loop, it can be even simpler :
Scanner scanner = new Scanner(System.in);
for (boolean flag = true; flag;) {
System.out.println("enter letter");
String bv = scanner.nextLine();
flag = bv.matches("a|b");
System.out.println(flag ? "you entered" + bv : ' ');
}
Or if you ok for having whitspace for first run:
Scanner scanner = new Scanner(System.in);
String aa=" ";
String bv=null;
for (boolean flag = true; flag;aa=(flag?"you entered: "+bv:" ")) {
System.out.println(aa);
System.out.println("enter letter");
bv = scanner.nextLine();
flag = bv.matches("a|b");
}
You can easily run a while loop until letter = "a" or letter = "b". Code will start the while loop with intial "" value of the letter and get the new value by scanner. Then it check the new value of the letter before starting the next round of the loop.
package com.company;
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter = "";
while(!(letter.equals("a") || letter.equals("b")))
{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
System.out.println("You entered: " + letter);
}
}
}
Similar as previous answer, but from a code readability perspective i would create an array of valid characters instead and use in condition. That results in the more "text like" condition below reading "if not validCharacters contains letter":
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
List<String> validCharacters = List.of("a", "b");
while (true) {
System.out.print("Enter a letter: ");
String letter = scan.nextLine();
if (!validCharacters.contains(letter)) {
break;
}
System.out.println("You entered: " + letter);
}
}
Your code just needed a little tweak to make it work, although you can use many more efficient approaches but here it is:
import java.util.Scanner;
public class Main
{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
String letter = "a";
while(letter.equals("a") || letter.equals("b"))
{
System.out.print("Enter a letter: ");
letter = scan.nextLine();
System.out.println("You entered: " + letter);
}
}
}
Im stuck on this, I need a code that use 2 nested loops for this assignment (there are other solutions, but I need to demonstrate my understanding of nested loops). But I just dont get it. The outer loop repeats the entire algorithm and the inner loop iterates half-way (or less) through the string. I am not sure on what I need to put inside the for loops. This is what I have so far. Any Assistance would be pleasured.
import java.util.Scanner;
public class pali
{
public static void main(String[] args)
{
String line;
Scanner input = new Scanner(System.in);
System.out.println("Enter a String to check if it's a Palindrome");
line = input.nextLine();
String x = 0;
String y = input.length-1;
for (String i = 0; i < line.length-1; i ++){
for (String j = 0; j < line.length-1; j ++){
if (input.charAt(x) == input.charAt(y))
{
x++;
y--;
}
}
}
}
Example Output:
Enter a string: 1331
1331 is a palindrome.
Enter a string: racecar
racecar is a palindrome.
Enter a string: blue
blue is NOT a palindrome.
Enter a string:
Empty line read - Goodbye!
Your algorithm is flawed, your nested loop should be to prompt for input - not to check if the input is a palindrome (that requires one loop itself). Also, x and y appear to be used as int(s) - but you've declared them as String (and you don't actually need them). First, a palindrome check should compare characters offset from the index at the beginning and end of an input up to half way (since the offsets then cross). Next, an infinite loop is easy to read, and easy to terminate given empty input. Something like,
Scanner input = new Scanner(System.in);
while (true) {
System.out.print("Enter a string: ");
System.out.flush();
String line = input.nextLine();
if (line.isEmpty()) {
break;
}
boolean isPalindrome = true;
for (int i = 0; i * 2 < line.length(); i++) {
if (line.charAt(i) != line.charAt(line.length() - i - 1)) {
isPalindrome = false;
break;
}
}
if (isPalindrome) {
System.out.printf("%s is a palindrome.%n", line);
} else {
System.out.printf("%s is NOT a palindrome.%n", line);
}
}
System.out.println("Empty line read - Goodbye!");
import java.util.Scanner;
public class pali
{
public static void main(String[] args)
{
String line;
Scanner input = new Scanner(System.in);
System.out.println("Enter a String to check if it's a Palindrome");
line = input.nextLine();
String reversedText ="";
for(int i=line.length()-1/* takes index into account */;i>=0;i++) {
reversedText+=line.split("")[i]; //adds the character to reversedText
}
if(reversedText ==line){
//is a palidrome
}
}
Your code had lot of errors. I have corrected them and used a while loop to check if its a palindrome or not. Please refer below code,
import java.util.Scanner;
public class Post {
public static void main(String[] args) {
String line;
boolean isPalindrome = true;
Scanner input = new Scanner(System.in);
while (true) {
System.out.println("Enter a String to check if it's a Palindrome");
line = input.nextLine();
int x = 0;
int y = line.length() - 1;
while (y > x) {
if (line.charAt(x++) != line.charAt(y--)) {
isPalindrome = false;
break;
}
}
if (isPalindrome) {
System.out.println(line + " is a palindrome");
} else {
System.out.println(line + "is NOT a palindrome");
}
System.out.println();
}
}
}
Here is my code:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner Keyboard = new Scanner(System.in);
{
System.out.println("What is the answer to the following problem?");
Generator randomNum = new Generator();
int first = randomNum.num1();
int second = randomNum.num2();
int result = first + second;
System.out.println(first + " + " + second + " =");
int total = Keyboard.nextInt();
if (result != total) {
System.out.println("Sorry, wrong answer. The correct answer is " + result);
System.out.print("DO you to continue y/n: ");
} else {
System.out.println("That is correct!");
System.out.print("DO you to continue y/n: ");
}
}
}
}
I'm trying to keep the program to continue but if the user enters y and closes if he enters n.
I know that I should use a while loop but don't know where should I start the loop.
You can use a loop for example :
Scanner scan = new Scanner(System.in);
String condition;
do {
//...Your code
condition = scan.nextLine();
} while (condition.equalsIgnoreCase("Y"));
That is a good attempt. Just add a simple while loop and facilitate user input after you ask if they want to continue or not:
import java.util.*;
class Main
{
public static void main(String [] args)
{
//The boolean variable will store if program needs to continue.
boolean cont = true;
Scanner Keyboard = new Scanner(System.in);
// The while loop will keep the program running unless the boolean
// variable is changed to false.
while (cont) {
//Code
if (result != total) {
System.out.println("Sorry, wrong answer. The correct answer is " + result);
System.out.print("DO you to continue y/n: ");
// This gets the user input after the question posed above.
String choice = Keyboard.next();
// This sets the boolean variable to false so that program
// ends
if(choice.equalsIgnoreCase("n")){
cont = false;
}
} else {
System.out.println("That is correct!");
System.out.print("DO you to continue y/n: ");
// This gets the user input after the question posed above.
String choice = Keyboard.next();
// This sets the boolean variable to false so that program
// ends
if(choice.equalsIgnoreCase("n")){
cont = false;
}
}
}
}
}
You may also read up on other kinds to loop and try implementing this code in other ways: Control Flow Statements.
I need help with looping my code in Java. So far I have:
import java.util.Scanner;
public class chara{
public static void main(String[]args){
int count = 0;
Scanner input = new Scanner(System.in);
System.out.println("Input a string");
String user=input.nextLine();
if(user.length()<7)
{
return;
}
else
{
}
System.out.println("Now input a letter to be replaced");
String letter = input.next();
if(letter.length()!=1)
{
return;
}
else
{
}
String user2 = user.replace(letter, "-");
String user3 = user.replace(letter, "");
count += (user.length() - user3.length());
System.out.println(user2);
System.out.println(user3);
System.out.println("#"+letter+"'s: "+count);
}
}
The code does everything I want it to except that when the string condition is not met (user<7, letter!=1) the program terminates and what I need it to do is ask the question again. Does anyone know how I can achieve this?
You need to put your looping code in method that can be called, then when the conidtion is not met you can go back to your question, and depending on that condidtion, quit the program, or call the loop method.
You just need a loop with a break condition, this should do it for you:
Scanner input = new Scanner(System.in);
System.out.println("Input a string");
String user=input.nextLine();
while (true)
{
if(user.length() <7 ) {break;}
input = new Scanner(System.in);
System.out.println("Too long, input a string < 7");
user=input.nextLine();
}
if(user.length()<7)......
A simple way would be to wrap your main logic within a loop with a boolean condition. This condition stays true when there is an "error" in the input. The condition is then false when the user proceeds as wanted.
Your code would look as so :
import java.util.Scanner;
public class Tester{
public static void main(String[]args){
int count = 0;
boolean keepGoing = true;
Scanner input = new Scanner(System.in);
while(keepGoing) {
System.out.println("Input a string");
String user=input.nextLine();
if(user.length()<7)
{
keepGoing = true;
//enter an error message here
}
else
{
System.out.println("Now input a letter to be replaced");
String letter = input.next();
if(letter.length()!=1)
{
keepGoing = true;
//enter an error message here
}
else
{
String user2 = user.replace(letter, "-");
String user3 = user.replace(letter, "");
count += (user.length() - user3.length());
System.out.println(user2);
System.out.println(user3);
System.out.println("#"+letter+"'s: "+count);
keepGoing = false;
}
}
}
input.close(); //Close resources
}
}
Unrelated
The convention is that class names start with a capital letter. In your case your class should be Chara, not chara.
Also, when opening resources make sure you close them. This is to avoid having resources leaked. Some IDEs will tell you something like this Resource leak: 'input' is never closed. It's a good idea to use a good IDE to help you with potential problems like this one.
Hi I have a question regarding the use of .nextLine and why it skips user input the second time around during the infinite loop. The .next function (letter input) still asks for user input everytime but the .nextLine function (phrase input) does not. Thanks.
import java.util.Scanner;
public class Lab6 {
public static void main (String [] args) {
Scanner in = new Scanner(System.in);
String phrase, l;
char letter;
while (true) {
System.out.println("Enter a phrase. Enter 'quit' to quit.");
phrase = in.nextLine();
if (phrase.startsWith("quit")) {
break;
}
System.out.println("Enter a letter");
l = in.next();
letter = l.charAt(0);
System.out.println("Phrase entered is: " + phrase);
System.out.println("Letter entered is: " + letter);
int i = 0;
int count = 0;
while (i < phrase.length()) {
if (phrase.charAt(i) == letter) {
count++;
}
i++;
}
System.out.println(count);
}
}
}
The reason is that Scanner.next() does not consume newline characters from the system input, so the input will be passed through to the statement:
phrase = in.nextLine();
which will now not block having received the input.