My calculator, that I needed to make for my test task to apply for a Java course, is working great. But there's an issue I would like to resolve. If you type in, for example, "5+3" as opposed to "5 + 3", it doesn't work. Can my calculator be smart enough to delimit input without explicit delimiters (like spaces)?
In other words, how do I make my scanner split, for example, an input of 5+32 *2 into five tokens: 5, +, 32, *, and 2? If I don't have to overhaul my entire code, that would be even better!
import java.util.Scanner;
import java.io.IOException;
import java.text.DecimalFormat;
public class Introduction {
private static double firstNum;
private static double secondNum;
private static double result;
private static boolean dontKnow;
private static String firstNumS;
private static String secondNumS;
private static String operationS;
private static final DecimalFormat df = new DecimalFormat("#.##");
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
firstNumS = scanner.next();
operationS = scanner.next();
secondNumS = scanner.next();
if(firstNumS.compareTo(operationS) > 15){
switch(firstNumS){
case "I":
firstNum = 1;
break;
case "II":
firstNum = 2;
break;
case "III":
firstNum = 3;
break;
case "IV":
firstNum = 4;
break;
case "V":
firstNum = 5;
break;
case "VI":
firstNum = 6;
break;
case "VII":
firstNum = 7;
break;
case "VIII":
firstNum = 8;
break;
case "IX":
firstNum = 9;
break;
case "X":
firstNum = 10;
break;
default:
System.out.println("I don't know the first number!");
dontKnow = true; }}
else {
firstNum = Integer.decode(firstNumS);
if(firstNum > 10){
System.out.println("It appears, the first number is too big for me!");
dontKnow = true;
}
}
if(secondNumS.compareTo(operationS) > 15) {
switch(secondNumS){
case "I":
secondNum = 1;
break;
case "II":
secondNum = 2;
break;
case "III":
secondNum = 3;
break;
case "IV":
secondNum = 4;
break;
case "V":
secondNum = 5;
break;
case "VI":
secondNum = 6;
break;
case "VII":
secondNum = 7;
break;
case "VIII":
secondNum = 8;
break;
case "IX":
secondNum = 9;
break;
case "X":
secondNum = 10;
break;
default:
System.out.println("I don't know the second number!");
dontKnow = true; }}
else {
secondNum = Integer.decode(secondNumS);
if(secondNum > 10) {
System.out.println("It appears, the second number is too big for me!");
dontKnow = true; }}
if(operationS.equals("+")) {
result = firstNum + secondNum; }
else if(operationS.equals("-")) {
result = firstNum - secondNum; }
else if(operationS.equals("*")){
result = firstNum * secondNum; }
else if(operationS.equals("/")){
result = firstNum / secondNum; }
else {
System.out.println("I don't know such an operation!");
dontKnow = true; }
if(!(operationS.equals("/") && secondNum == 0)) {
if(!dontKnow) {
if(result / (int)result != 1) {
if(String.valueOf(result).equals(df.format(result))) {
System.out.println("It's " + result + "!"); }
else {
System.out.println("It's approximately " + df.format(result) + "!"); }}
else {
System.out.println("It's " + (int)result + "!"); }}}
else {
if(!dontKnow) {
System.out.println("Gosh! I tried to divide it by zero, as you requested, but my virtual head nearly exploded! I need to recover..."); }
else {
System.out.println("Besides, you can't even divide by zero, I'm so told!"); }}
}
}
Assuming you're using scanner, yes, it could. The scanner operates on the notion that a regexp serves as delimiter: Each match of the regex delimits, and whatever the regexp matches is tossed out (because nobody 'cares' about reading the spaces or the commas or whatever). The scanner then gives you stuff in between the delimiters.
Thus, for you to end up with scanner stream '5', '+', and '3', you want a delimiter that delimits on the space between '5' / '+' and '+' / '3', whilst matching 0 characters otherwise those would be thrown out.
You can do that, using regexp lookahead/lookbehind. You want a digit to the left and an operator to the right, or vice versa:
String test = "53 + 2*35- 8";
Scanner s = new Scanner(test);
s.useDelimiter("\\s+|(?:(?<=\\d)(?=[-+/*]))|(?:(?=\\d)(?<=[-+/*]))");
while (s.hasNext()) {
System.out.println("NEXT: '" + s.next() + "'");
}
To break that convoluted regex open:
A|B|C means: A or B or C. That's the 'outermost' part of this regexp, we're looking for one of 3 distinct things to split on.
\\s+ means: 1 or more whitespace characters. Thus, input "5 20" would be split into 5 and 20. The whitespace is consumed (i.e. tossed out and not part of your tokens).
OR, positive lookbehind ((?<=X) means: Match if, looking backwards, you would see X), and X is \\d here - a digit. We then also have a positive lookahead: (?=X) means: Check for X being here, but don't consume it (or it would be thrown out, remember, the regex describes the delimiter, and the delimiter is thrown out). We look ahead for one of the symbols.
OR, that, but flipped about (first an operator, then a digit).
NB: If you want to avoid the complexity of a regexp, you could just loop through each character, but you'd be building a little state machine, and have to take care of consecutive, non-space separated digits: You need to combine those (10 + 20 is not 1, 0, +, 2, 0 - it's 10 + 20).
NB2: If you also want to support ( and ) you can edit the regex appropriately (They are, essentially, 'operators' and go in the list of operators), however, at some point you're essentially descriving a grammar for a formal language and should start looking into a parser generator. But that's all vastly more complicated than any of this.
Related
I'm having a task to solve in which I have to find the biggest sum between the digits of 3nums integer.
I've decided to do it with "switch case", because I am still a newbie.
But, unfortunately when I run it, it skips directly out after the loop.
Here's my code:
import java.util.Scanner;
public class Game {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String input = scanner.nextLine();
int nums = Integer.parseInt(input);
int firstNum, secondNum, thirdNum, sumNums, sumNums2 = 0;
firstNum = Character.getNumericValue(input.charAt(0));
secondNum = Character.getNumericValue(input.charAt(1));
thirdNum = Character.getNumericValue(input.charAt(2));
switch (nums) {
case 1:
sumNums = firstNum + secondNum + thirdNum;
sumNums2 = sumNums;
case 2:
sumNums = firstNum + secondNum * thirdNum;
if (sumNums > sumNums2) {
sumNums2 = sumNums;
}
case 3:
sumNums = firstNum * secondNum + thirdNum;
if (sumNums > sumNums2) {
sumNums2 = sumNums;
}
case 4:
sumNums = firstNum * thirdNum + secondNum;
if (sumNums > sumNums2) {
sumNums2 = sumNums;
}
case 5:
sumNums = firstNum * secondNum * thirdNum;
if (sumNums > sumNums2) {
sumNums2 = sumNums;
break;
}
}
System.out.println(sumNums2);
}
}
Thanks in advance!
The issue is that you are switching on the variable nums, which you are expecting a 3 digit number. Any 3 digit number entered will not match any of your single digit case statements, so it falls out of the switch all together.
It appears that you are intending to have the user first input a singer digit number 1 thru 5 representing an operation to match one of the cases - you never do that.
Also, you should first print out via a System.out.println() statement what input you are asking for before scanning for input.
The code looks odd:
switch (nums) { // 111, 257 wrong input, no match
// suggest to add default, so you can debug the problem
}
I am a complete noob to Java, but I wish to make a program that takes an input from user, [A/a] - [C/c], [D/d] - [F/f], and so on, and then returns a value ([A/a-C/c = 1], [D/d-F/f = 2]....
If the input is not A-Z or a-z, returns a "Invalid input". (I think I can figure this one out myself).
I suppose I could make a "ToUpperCase" statement on the input, but I am not entirely sure how to do so.
I would prefer not to use any special databases.
Here is my code so far:
import java.util.Scanner;
public class TelefonTastatur {
public static void main(String[] args) {
String korrTall = "Korresponderer til tallet "; //Strings are in Norwegian, but I don't need help with those :-)
System.out.println("Dette programmet konverterer bokstav-input til korresponderende tall på et telefontastatur.");
System.out.println("Oppgi en bokstav (A-Z: "); //Asks user for A-Z input.
Scanner sc = new Scanner(System.in);
char c = sc.next().charAt(0); //Perhaps toUpperCase to lower number of switch cases?
switch (c) {
case ('A'-'C'): //Not sure how to make A-C and/or a-c. I could make an individual case for all inputs, but that would make a lot of code.
case ('a'-'c'):
System.out.print(korrTall + "2.");
break;
case (D/d - F/f):
case ():
System.out.print(korrTall + "3.");
break;
case (G/g - I/i):
case ():
System.out.print(korrTall + "4.");
break;
case (J/j - L/l):
case ():
System.out.print(korrTall + "5.");
break;
case (M/m - O/o):
case ():
System.out.print(korrTall + "6.");
break;
case (P/p - S/s):
case ():
System.out.print(korrTall + "7.");
break;
case (T/t - V/v):
case ():
System.out.print(korrTall + "8.");
break;
case (W/w - Z/z):
case ():
System.out.print(korrTall + "9.");
break;
case 'F':
case 'f':
System.out.print(korrTall + "0.");
break;
default:
System.out.println("Det du har tastet inn tilsvarer ikke noe tall på et telefontastatur.");
break;
}
}
}
If you want to read a single letter from the user you can use the readInput()provided in the code snippet.
Then, for example in your main(), you could ask for the user to input 2 letters and then you will provide him the result.
public static void main(String[] args) {
try{
char inputOne = readInput();
char inputTwo = readInput();
handle(inputOne,inputTwo);
}catch(Exception e){
System.out.println(e.getMessage());
}
}
static char readInput(){
System.out.println("Insert a character");
String input = Console.readLine();
if (input.length==0) {
char c = input.charAt(0);
if (Character.isLetter(c)) {
return c;
}
}
throw new Exception("Invalid input!");
}
static void handle(char a, char b){
// your logic to handle the input of the user
}
Your question is not clear at all but i try to help you. Next time post what u tried.
This simple code will help you, this can be improved so let's do this :D
Scanner scanner = new Scanner(System.in);
System.out.println("Insert first char");
String firstChar = scanner.next().toUpperCase();
if (firstChar.length() != 1 || (firstChar.toCharArray()[0] < 65 || firstChar.toCharArray()[0] > 90)) {
System.out.println("Please, insert one single character [a-z/A-Z]");
return;
}
System.out.println("Insert second char");
String secondChar = scanner.next().toUpperCase();
if (secondChar.length() != 1 || (secondChar.toCharArray()[0] < 65 || firstChar.toCharArray()[0] > 90)) {
System.out.println("Please, insert one single character");
return;
}
System.out.println(firstChar + " - " + secondChar + " = " + Math.abs(firstChar.toCharArray()[0] - secondChar.toCharArray()[0]));
Note that You can create methods to do repetitive action. In this simple example you can create a method that check if what you just read from keyboard is a single character.
One other improve you can do is handle when user insert something wrong.
Let's try to code :D
Bye
You're going to have to use the Scanner class to accomplish user input.
import java.util.Scanner;
Then create a variable that takes in the keyboard input.
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a letter: ");
String text = keyboard.nextLine();
Create a method that returns a number given a character.
a-z is equal to 97-122 in Java, and A-Z is equal to 65-90.
public int toNum(String text) {
//Ensure that the text is only 1 character long.
if(text.length() > 1) return -1;
//Convert the one-character String to type char.
char letter = text.charAt(0);
//Convert char to its equivalent number value.
int rawNum = letter;
int newNum;
//Convert the number to a value 0-25.
if(rawNum >= 'a' && rawNum <= 'z') {
newNum = rawNum - 'a';
} else if(rawNum >= 'A' && rawNum <= 'Z') {
newNum = rawNum - 'A';
} else {
//None of the characters were letters A-Z.
System.out.println("Invalid input");
return -1;
}
//If {a,b,c} are 1 and {d,e,f} are 2, then {0,1,2} -> 1 and {3,4,5} -> 2
//Take the floor of the new number divided by 3.
int toReturn = Math.floor(newNum / 3.0) + 1;
return toReturn;
}
Now just call your method with the user input.
toNum(text);
You can print the returned value of the user input as well.
System.out.println(toNum(text));
I have composed a program that converts a hex number to decimal. For the most part it works, However, when I input a non-hexadecimal string, it computes that value correctly and displays it as a non-hexadecimal number, but it also jumps to the next line and outputs it as well. I think this is the part of the code which is problematic:
for (int i = 0; i < hexInput.length (); i++){
int value = hexValue (hexInput.charAt(i));
if (value == -1){
System.out.println ("You must enter a hexadecimal number. Try again
please.");
}
This correctly identifies incorrect input and the println statement is executed. However, it also executes the next line of code:
System.out.println("The hexadecimal number, " + hexInput + ", in base 10, is " + hexDecimalConversion (hexInput) + "." );
Consequently, if an incorrect digit--say j--is entered, the result is:
You must enter a hexadecimal number. Try again please.
The hexadecimal number, j, in base 10, is -1.
I want to get rid of the second line, and resume the loop so the user can enter another number.
I just need to know how to resume the program from the beginning, without the last line of code been executed, when an incorrect digit(s) has been entered.
Here is the entire program:
import java.util.Scanner;
public class HexBinaryConversion {
//method takes string as input, converts string to decimal
//using hexvalue method.
public static long hexDecimalConversion(String hexInput) {
long value = 0;
for (int i = 0; i < hexInput.length(); i++) {
value = value * 16 + hexValue(hexInput.charAt(i));
}
return value;
} //end of HexDecimalConversion method.
//method takes character as input and converts it to
//appropriate hexadecimal value.
public static int hexValue(char ch) {
switch (ch) {
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
case 'a':
case 'A':
return 10;
case 'b':
case 'B':
return 11;
case 'c':
case 'C':
return 12;
case 'd':
case 'D':
return 13;
case 'e':
case 'E':
return 14;
case 'f':
case 'F':
return 15;
default:
return -1;
}
} //end of hexValue method.
public static void main(String[] args) {
Scanner stdin = new Scanner (System.in);
String hexInput = "0";
while (!hexInput.equalsIgnoreCase ("x")){
System.out.println("Enter a hexadecimal number or enter x to terminate
the program: ");
hexInput = stdin.next();
if (hexInput.equalsIgnoreCase ("x")) {
System.out.println ("Thank you for using this program.");
break;
}
long answer = hexDecimalConversion (hexInput);
for (int i = 0; i < hexInput.length (); i++){
int value = hexValue (hexInput.charAt(i));
if (value == -1){
System.out.println ("You must enter a hexadecimal number. Try again
please.");
break;
}
}
System.out.println("The hexadecimal number, " + hexInput + ", in base
10, is " + answer + "." );
}//end of while loop.
}//end of main ().
}//end of class.
And this is the output:
run:
Enter a hexadecimal number or enter x to terminate the program:
a
The hexadecimal number, a, in base 10, is 10.
Enter a hexadecimal number or enter x to terminate the program:
45
The hexadecimal number, 45, in base 10, is 69.
Enter a hexadecimal number or enter x to terminate the program:
j
You must enter a hexadecimal number. Try again please.
The hexadecimal number, j, in base 10, is -1.
**************************incorrect line***************************
Enter a hexadecimal number or enter x to terminate the program:
ll
The hexadecimal number, ll, in base 10, is 17.
Enter a hexadecimal number or enter x to terminate the program:
x
Thank you for using this program.
BUILD SUCCESSFUL (total time: 36 seconds)
You are printing the result even when you have invalid values. You test for -1, print an error message, and the flow continues to System.out.println, and it should never get there.
Change this:
if (value == -1){
System.out.println ("You must enter a hexadecimal number. Try again please.");
break;
}
}
System.out.println("The hexadecimal number, " + hexInput + ", in base 10, is " + answer + "." );
To this:
if (value == -1){
System.out.println ("You must enter a hexadecimal number. Try again please.");
break;
} else {
System.out.println("The hexadecimal number, " + hexInput + ", in base 10, is " + answer + "." );
}
}
And a tip: don't use a lookup table for converting Hex to Decimal. You can use regex to remove unwanted chars, and parseInt to convert directly:
int intValue = Integer.parseInt(hexString.replaceAll("[^a-fA-F0-9]", ""), 16);
Test for x before parsing, and you are done.
I am new to Java and I am trying to make a program that will take a string, such as 'asdfg', and print words and a total number that are associated with these letters.
So 'a' would be 'apple' and its assigned number is 10, 's' would be spinach, and its assigned number is 5, 'd' would be 'dog' and its assigned number would be 15, 'f' would be 'frog' and its assigned number would be 20 and 'g' would be 'goat' and its assigned number would be 25. The output would look something like 'apple spinach dog frog goat 75'.
The code I have so far is
import java.util.Scanner;
import java.util.ArrayList;
import java.io.*;
public class PizzaTwo {
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the details of your order");
String myList = scan.nextLine();
for (int i = 0; i < myList.length(); i++) {
int letNum = 0;
switch (myList.charAt(i)) {
case 'a':
System.out.println("apple" + letNum);
letNum += 10;
break;
case 's':
System.out.println("spinach" + letNum);
letNum += 5;
break;
case 'd':
System.out.println("dog" + letNum);
letNum += 15;
break;
case 'f':
System.out.println("frog" + letNum);
letNum += 20;
break;
case 'g':
System.out.println("goat", letNum);
letNum += 25;
break;
default:
System.out.println("Nothing..");
break;
}
}
}
}
Thank you for any help.
First of all, I'd like to suggest you use better names for variables.
You were resetting the "letNum" in each loop, then I've moved it out of the loop.
I recommend read about String and StringBuilder.
String objects are immutable, so instead to create more variables to concatenate "flavors", I used StringBuilder that are mutable.
Strings are constant; their values cannot be changed after they are created
The principal operations on a StringBuilder are the append and insert methods, which are overloaded so as to accept data of any type
import java.util.Scanner;
public class PizzaTwo {
public static void main(String[] args) throws Exception {
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the details of your order");
String flavors = scan.nextLine();
int price = 0;
StringBuilder order = new StringBuilder();
for (int i = 0; i < flavors.length(); i++) {
switch (flavors.charAt(i)) {
case 'a':
order.append("apple ");
price += 10;
break;
case 's':
order.append("spinach ");
price += 5;
break;
case 'd':
order.append("dog ");
price += 15;
break;
case 'f':
order.append("frog ");
price += 20;
break;
case 'g':
order.append("goat ");
price += 25;
break;
default:
order.append("No flavor added ");
break;
}
}
System.out.println(order.append(price));
}
}
It looks like you want the numbers to only appear after all the words have been printed, from your description "apple spinach dog frog goat 75", but your code looks like it's trying to append the number to the end of each word.Assuming you want the output to be like your sample output, don't try to print the numbers after each word, instead after all the words have been printed print the variable you've been using to accumulate each letters value, 'letNum' in your code.Also, don't reset 'letNum' each time you deal with a new letter.
Take 2 separate variables, 1 string and another number. Each time concatenate with existing string, means something like String s=""; int n=0; s+="Apple"; n+=10; s+="frog";
....
Now when loop is done print string then the number.
I'm learning Java and I need to write a program that converts Roman numerals and traditional integers.
The code only accepts the letters MDCLXVI as Roman numerals. It does not accept any number.
This is my code:
System.out.print("Enter a roman numeral");
Scanner keyb = new Scanner(System.in);
String roman = keyb.next();
if(roman.matches(".*[0-9].*") || **something different then M, D, C, L, X, V or I**)
{
System.out.println("Wrong! Re-type.");
}
The problem that I'm trying to solve is how to write the second condition of the If.
first off all you have to check if the given Roman number is valid or not. So the method could look like the following:
public static boolean isValid(String romanNumber) {
String pattern = "[m|d|c|l|x|v|i]*";
Pattern p = Pattern.compile(pattern);
Matcher m = p.matcher(romanNumber);
return m.matches();
}
Then you can use this one inside your converter method. After you made this, it is necessary to convert each character inside your Roman string. So you can go ahead by creating a switch-function, which can be used inside of a for-loop.
public static int convertCharacter(String romanNumber, int position) {
char c = romanNumber.charAt(position);
switch (c) {
case 'm':
return 1000;
case 'd':
return 500;
case 'c':
return 100;
case 'l':
return 50;
case 'x':
return 10;
case 'v':
return 5;
case 'i':
return 1;
default:
return 0;
}
}
And due to fact that you are new to Java, I will show you, how the converter method could be written. This one is not the best solution, but it worked for me. Using this one, it will also be possible to convert numbers like "MCMXCIX".
I deleted the comments. So try to understand what the code does. Otherwise you won't learn from it.
public static int convertRomanNumber(String romanNumber) {
romanNumber = romanNumber.toLowerCase();
if (!isValid(romanNumber)) {
System.out.println("Invalid character detected");
System.exit(0);
}
int result = 0;
int currentNumber;
int nextNumber;
for (int i = 0; i < romanNumber.length(); i++) {
currentNumber = convertCharacter(romanNumber, i);
if (i < romanNumber.length() - 1) {
nextNumber = convertCharacter(romanNumber, i + 1);
if (nextNumber > currentNumber) {
result += currentNumber * -1;
} else {
result += currentNumber;
}
} else {
result += currentNumber;
}
}
System.out.println("Your input: " + romanNumber.toUpperCase());
return result;
}
I hope it helps you for the future.
All the best.
First I use toLowerCase() to lower case the user input, then use matches() to check whether the user input is equal to the character of M D C L X V I.
String user_input = "M";
if (user_input.toLowerCase().matches("m|d|c|l|x|v|i")){
System.out.println("Matches");
}
you can use this:
if(roman.matches(".*[0-9].*") ||
!roman.matches("[MDCLXVI]"))
this for case insensitive:
if(roman.matches(".*[0-9].*") ||
!roman.matches("(?i)[MDCLXVI]"))