The project is asking to use Stack to calculate a postfix expression, this one in particular:
5.0 3.5 - 1.2 /
Now my code works fine for this postfix expression:
2 3 +
What am I missing that is giving me the following error?
Exception in thread "main" java.lang.NumberFormatException: empty
String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110) at
java.lang.Double.parseDouble(Double.java:538) at
java.lang.Double.(Double.java:608) at
project.Calculator.processIn(Calculator.java:55) at
project.Project_main.main(Project_main.java:25) Java Result: 1
package project;
import java.util.ArrayList;
import java.util.Stack;
public class Calculator {
Stack<Double> calcStack = new Stack<>();
ArrayList<String> operators = new ArrayList<>();
public Calculator() {
operators.add("+");
operators.add("-");
operators.add("/");
operators.add("*");
}
public double processIn(String expression){
String[] express = expression.split("");
String temp = "";
for(String j : express){
if(operators.contains(j)){
System.out.println("Operator Reached: " + j);
double operand2 = calcStack.pop();
double operand1 = calcStack.pop();
double tmp = 0.0;
if(j.compareTo("*") == 0){
tmp = operand1 * operand2;
System.out.println("Performing multiplication on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
else if(j.compareTo("/") == 0){
tmp = operand1 / operand2;
System.out.println("Performing division on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
else if(j.compareTo("-") == 0){
tmp = operand1 - operand2;
System.out.println("Performing subtraction on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
else if(j.compareTo("+") == 0){
tmp = operand1 + operand2;
System.out.println("Performing addition on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
System.out.println("Pushing result to stack: " + tmp);
}
else if(j.compareTo(" ") == 0){
double newOperand = new Double(temp);
temp = "";
System.out.println("Pushing to stack: " + newOperand);
calcStack.push(newOperand);
}
else{
temp = temp + j;
System.out.println("Current temp value: " + temp);
}
}
return calcStack.pop();
}
}
i think this will solve your problem.
split with " "(space) instead of ""
String[] express = expression.split(" ");
and change your else to bellow
else {
double newOperand = new Double(j);
System.out.println("Pushing to stack: " + newOperand);
calcStack.push(newOperand);
}
and remove else if bellow
else if(j.compareTo(" ") == 0){
double newOperand = new Double(temp);
temp = "";
System.out.println("Pushing to stack: " + newOperand);
calcStack.push(newOperand);
}
this way you directly add numbers to your stack.
your error was happening because of how you handle space after operations. when you have numbers followed by numbers else gets called first and then if for space. so you temp value has a number in it. but after finishing an operation you reach a space gain right away but you have no value in your temp so new Double(temp) throws an exception since temp is not a number.
so another way to fix your code if you want to keep it as it is, is to use try and catch like below.
else if(j.compareTo(" ") == 0){
try{
double newOperand = new Double(temp);
temp = "";
System.out.println("Pushing to stack: " + newOperand);
calcStack.push(newOperand);
}catch(NumberFormatException ex){
//skip
}
}
this way you catch your error without breaking your code. but i recommend the first solution.
Please split the string on space " " as Shawn suggested like expression.split(" ") (but this assumes that your expression would always contains spaces between operator and operands). This would give you two types of tokens/strings operands and operators. Here is more simplified implementation of your code. Please notice the expression.trim() operation to avoid any trailing spaces.
[BTW, I have tried in eclipse and it works :) ]
public double processIn(String expression)
{
expression = expression.trim();
System.out.println("Trimmed expressoin : " + expression);
String[] express = expression.split(" ");
for(String j : express){
if(operators.contains(j)){
System.out.println("Operator Reached: " + j);
double operand2 = calcStack.pop();
double operand1 = calcStack.pop();
double tmp = 0.0;
if(j.compareTo("*") == 0){
tmp = operand1 * operand2;
System.out.println("Performing multiplication on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
else if(j.compareTo("/") == 0){
tmp = operand1 / operand2;
System.out.println("Performing division on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
else if(j.compareTo("-") == 0){
tmp = operand1 - operand2;
System.out.println("Performing subtraction on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
else if(j.compareTo("+") == 0){
tmp = operand1 + operand2;
System.out.println("Performing addition on " + operand1 + " and " + operand2);
calcStack.push(tmp);
}
System.out.println("Pushing result to stack: " + tmp);
}
else {
double newOperand = new Double(j);
System.out.println("Pushing operand to stack: " + newOperand);
calcStack.push(newOperand);
}
}
return calcStack.pop();
}
Related
I'm a very beginner java coder and I'm coding a simple calculator using swing, and I want to implement square roots into the operators. I want it to be so that in the case that the operator is a square root, the calculator wont ask for the second number.
package swingcalculator;
import javax.swing.JOptionPane;
public class SwingCalculator {
public static void main(String[] args) {
double num1, num2, answer;
String operator;
num1 = Integer.parseInt(JOptionPane.showInputDialog("Enter your first number:"));
operator = JOptionPane.showInputDialog("Enter your operator (+ , - , * , /, ^, sqrt):");
num2 = Integer.parseInt(JOptionPane.showInputDialog("Enter your second number number:"));
switch(operator) {
case "+":
answer = num1 + num2;
break;
case "-":
answer = num1 - num2;
break;
case "*":
answer = num1 * num2;
break;
case "/":
answer = num1 / num2;
break;
case "sqrt":
answer = Math.sqrt(num1);
break;
case "^":
answer = Math.pow(num1, num2);
break;
default:
System.out.println("You have entered an invalid operator");
return;
}
if (Boolean.parseBoolean(operator) == Boolean.parseBoolean("sqrt")){
JOptionPane.showMessageDialog(null, "Square root of " + num1 + " = " + answer);
}
else{
JOptionPane.showMessageDialog(null, num1 + " " + operator + " " + num2 + " = " + answer);
}
}
Any help would be appreciated!
Put everything after the operator = line inside a conditional (you can also move the JOptionPane.showMessageDialog lines inside the appropriate block of the conditional statement, because you don't need to check operator again):
operator = JOptionPane.showInputDialog("Enter your operator (+ , - , * , /, ^, sqrt):");
if (!operator.equals("sqrt")) {
num2 = Integer.parseInt(JOptionPane.showInputDialog("Enter your second number number:"));
switch (...) { ... }
JOptionPane.showMessageDialog(null, num1 + " " + operator + " " + num2 + " = " + answer);
} else {
JOptionPane.showMessageDialog(null, "Square root of " + num1 + " = " + answer);
}
operator = JOptionPane.showInputDialog("Enter your operator (+ , - , * , /, ^, sqrt):");
if(!operator.equals("sqrt"){
num2 = Integer.parseInt(JOptionPane.showInputDialog("Enter your second number number:"));
}
Read the second number only if operator is not 'sqrt', however your program seems to have many anomalies, as suggested to you in comments by others
I need some with evaluating math expressions in a string.
As of now my code will work for only positive numbers.
I used regex to split the string into two separate arrays. I was able to split all the math signs in one array and all the numbers in the other. But I am unsure how to do it for negative numbers. (I dont understand the regex i just put stuff and it worked but not for negative numbers)
Anyways here is my code, Thanks in advance!`
boolean mybool = true;
String str = "1.0+2.0+3.0+4.0";
String[] numarray = str.split("[-+/%*]");
String[] signarray = str.split("[0123456789.]");
double result = 0.0;
double num1 = 0.0;
double num2 = 0.0;
String mystr = "";
//Adds each element in sign array to mystr
for(String e : signarray){
if(e != ""){
mystr+=e;
}
}
//Assign signarray new size of length mystr
signarray = new String[mystr.length()];
//Cycle through each element in str and add it to signarray
for(int i = 0; i < mystr.length(); i++){
signarray[i] = mystr.charAt(i)+"";
}
//Print each element in num array
System.out.print("Print each element in number array: ");
for(String e : numarray){
System.out.print(e+ " ");
}
System.out.println();
System.out.print("Print each element in sign array: ");
//print each element in sign array
for(String e : signarray){
System.out.print(e+ " ");
}
System.out.println();
//Prints each element in sign array and element value
for(int i = 0; i < signarray.length; i++){
System.out.println("SignArray[" + i + "] = " + signarray[i]);
}
for(int i = 2; i <= numarray.length; i++){
//this will get the first two indexes of number array
//and store them in num1 and num1 then i use another if
//statement to go sign array to get a sign to evaluate the
//two nums and store the value in result.
//hopefully you understand my logic
if(mybool == true){
num1 = Double.parseDouble(numarray[0]);
num2 = Double.parseDouble(numarray[1]);
System.out.println("num1 = " + num1);
System.out.println("num2 = " + num2);
if(signarray[0].equals("+")){
result = num1 + num2;
System.out.println("Result = num1 + num2 = " + num1 + "+" + num2 + "= " + result );
} else if(signarray[0].equals("-")){
result = num1 - num2;
System.out.println("Result = num1 - num2 = " + num1 + "-" + num2 + "= " + result );
} else if(signarray[0].equals("/")){
result = num1 / num2;
System.out.println("Result = num1 / num2 = " + num1 + "/" + num2 + "= " + result );
} else if(signarray[0].equals("*")){
result = num1 * num2;
System.out.println("Result = num1 * num2 = " + num1 + "*" + num2 + "= " + result );
} else if(signarray[0].equals("%")){
result = num1 % num2;
System.out.println("Result = num1 % num2 = " + num1 + "%" + num2 + "= " + result );
}
mybool = false;
} else {
num2 = Double.parseDouble(numarray[i-1]);
System.out.println("Num2 = " + num2);
if(signarray[i-2].equals("+")){
result = result + num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("-")){
result = result - num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("/")){
result = result / num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("*")){
result = result * num2;
System.out.println("Result after math is : " + result);
} else if(signarray[i-2].equals("%")){
result = result % num2;
System.out.println("Result after math is : " + result);
}
}
}`
Output:
Print each element in number array: 1.0 2.0 3.0 4.0
Print each element in sign array: + + +
SignArray[0] = +
SignArray[1] = +
SignArray[2] = +
num1 = 1.0
num2 = 2.0
Result = num1 + num2 = 1.0+2.0= 3.0
Num2 = 3.0
Result after math is : 6.0
Num2 = 4.0
Result after math is : 10.0
eventually i wanna be able to evaluate a string like this
//String str = "3.01+2.2/4.01*7.1%4.0--2.0";
but i dont know how to get negative numbers from sting and store in the num array.
Thanks for you help!
Ideally, you should use a parser instead of regex. However given your current requirements, it would be simple to use positive and negative lookbehinds.
(1). Operators are always preceded by a decimal number. So we split the arguments by matching any operator which appears after a decimal number (positive lookbehind).
String[] arguments = str.split("(?<=\\d)[-+/%*]");
(2). Arguments may start with an optional minus sign but are never preceded by another decimal number. So we split the operators by matching arguments not after a decimal number (negative lookbehind).
String[] operators = str.split("(?<!\\d)-?[0-9.]+");
Note however that there will be an empty operator at position 0 of the array. If you want to avoid this then there are many different methods you could use instead of String.split.
My code works, but what I need it to do is when nothing is enter the evaluation for the highest and the lowest should be N/A. Right now all it displays is the max and min number when something isn't entered.
Example:
Press K for keyboard or F to read expressions from a file OR escape to exit:
k
Please Enter a Post-Fix Expression (eg: 5 2 *)
Application Closed
Evaluations complete....
Highest Value: -3.4028235E38
Lowest Value: 3.4028235E38
Agregate result: 0.0
Average result: NaN
Valid expressions: 0.0
Invalid Expressions: 0.0
I need the ones in bold to say n/a but i don't know how.
private static void keyboardService(){
while (true){
System.out.println("Please Enter a Post-Fix Expression (eg: 5 2 *)");
String postfix=keyboard.nextLine();
String [] elements =postfix.split(" ");
if (postfix.equals("")){
System.out.println("Application Closed");
evaluation();
System.exit(0);
}
if (elements.length == 3){
try{
num1 = Float.valueOf(elements[0]);
num2 = Float.valueOf(elements[1]);
float total;
if(elements[2].equals("+")){
total = num1 + num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else if(elements[2].equals("*")){
total = num1 * num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else if(elements[2].equals("/")){
total = num1 / num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else if(elements[2].equals("-")){
total = num1 - num2;
display(total + " = " + num1 + elements[2] + num2);
valid_count = valid_count + 1;
calc(total);
}
else{
display("Error Invalid Expression: "+ postfix);{
invalid_count = invalid_count + 1;
}
}} catch(NumberFormatException e){
display("Error Invalid Expresion: "+postfix);
invalid_count = invalid_count + 1;
} //end of second if
} else {
display("Error Invalid Expression: "+ postfix);
invalid_count = invalid_count + 1;
}
}
}//end of keyboard service
////////////////////////////////////////////////////////////////////////////////////////////////////////
private static void calc(float total){
highest = Math.max(highest, total );
lowest= Math.min(lowest, total);
aggregate = aggregate + total;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////
private static void evaluation(){
display("Evaluations complete....");
display("Highest Value: " + highest);
display("Lowest Value: " + lowest);
display("Agregate result: " + aggregate );
display("Average result: " + aggregate/valid_count);
display("Valid expressions: " + valid_count);
display("Invalid Expressions: " + invalid_count);
}
}
Here you go:
display("Highest Value: " + (highest == Float.MIN_VALUE ? "N/A" : String.valueOf(highest)));
display("Lowest Value: " + (lowest == Float.MAX_VALUE ? "N/A" : String.valueOf(lowest)));
and so on
In the evaluation method, before you print, check highest and lowest.
if (highest < 0)
display("Highest Value: " + "N/A");
else
display("Highest Value: " + highest);
Beside the fact that a better structure for you code would be the prefered solution you could achieve it with following changes in your code.
in your method ` keyboardService()
...
String [] elements =postfix.split(" ");
boolean validInput = true;
if (postfix.equals("")){
validInput = false;
in your method evaluation()
display("Highest Value: " + (validInput ? highest : "n/a"));
display("Lowest Value: " + (validInput ? lowest : "n/a"));
display("Agregate result: " + (validInput ? aggregate : "n/a"));
display("Average result: " + (validInput ? aggregate / valid_count : "n/a"));
display("Valid expressions: " + valid_count);
display("Invalid Expressions: " + invalid_count);
import java.io.PrintStream;
import java.util.Scanner;
public class BasicCalculator
{
public static void main(String[] args)
{
int ADDITION = 1;
int SUBTRACTION = 2;
int MULTIPLICATION = 3;
int DIVISION = 4;
int EXIT = 5;
Scanner keyboard = new Scanner(System.in);
int choice;
do
{
System.out.println("Choose from the following:");
System.out.println("1. Add 2 integers");
System.out.println("2. Subtract 2 integers");
System.out.println("3. Multiply 2 integers");
System.out.println("4. Divide 2 integers");
System.out.println("5. Exit");
System.out.print("Enter choice: ");
choice = keyboard.nextInt();
if ((choice == 1) || (choice == 2) || (choice == 3) || (choice == 4))
{
System.out.print("Enter first integer: ");
int left = keyboard.nextInt();
System.out.print("Enter second integer: ");
int right = keyboard.nextInt();
switch (choice)
{
double Result;
case 1:
Result = left + right;
System.out.println(left + " + " + right + " = " + Result);
break;
case 2:
Result = left - right;
System.out.println(left + " - " + right + " = " + Result);
break;
case 3:
Result = left * right;
System.out.println(left + " * " + right + " = " + Result);
break;
case 4:
Result = left / right;
System.out.println(left + " / " + right + " = " + Result);
}
System.out.println();
}
} while (choice != 5);
}
}
errors:
BasicCalculator.java:34: error: case, default, or '}' expected
int Result;
^
BasicCalculator.java:34: error: case, default, or '}' expected
int Result;
^
BasicCalculator.java:34: error: case, default, or '}' expected
int Result;
the above code is my project for my intro to computer programming class,i've ran into a few errors that are stemming from formatting issues. can I get some basic help with whats causing the errors. I'm still trying to get used to reading the errors description in notepad++ and understanding what they mean.
You cannot declare a variable inside a switch statement outside of a case label. If you want Result to be shared among all cases, including the default, declare it prior to switch, like this:
double Result = 0;
switch (choice)
{
case 1:
Result = left + right;
System.out.println(left + " + " + right + " = " + Result);
break;
case 2:
Result = left - right;
System.out.println(left + " - " + right + " = " + Result);
break;
case 3:
Result = left * right;
System.out.println(left + " * " + right + " = " + Result);
break;
case 4:
Result = left / right;
System.out.println(left + " / " + right + " = " + Result);
}
(I'm not sure this is completely correct as I don't really do Java, but here goes)
I think the error is where you have double Result; inside the switch statement - Java only allows either case or default inside the switch statement. Try placing the double Result line just above your switch (... line. Also, I'd make sure that all of the lines below your case 1/2/3 statements are properly indented - it may just be the formatting on stack exchange, but the Result = ... lines look one character ahead (not sure if this would make a difference, but it's best to always have consistent code).
I need to let the user input an operand, input 2 integers, display the result, and repeat. It wont repeat and when you input an integer to continue, it terminates. Any help would be appreciated, Ive been stuck for a while now! Thanks.
package lab03;
import java.util.Scanner;
import javax.swing.JOptionPane;
/**
*
*/
public class Lab03 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
int n, p, q = 1;
boolean run = true;
String operator;
while (run == true) {
operator = JOptionPane.showInputDialog("Enter one of + - * / ");
String trimOperator = operator.trim();
char m = trimOperator.charAt(0);
String firstOperand = JOptionPane
.showInputDialog("Enter first integer operand: ");
n = Integer.parseInt(firstOperand);
String secondOperand = JOptionPane
.showInputDialog("Enter second integer operand: ");
p = Integer.parseInt(secondOperand);
switch (m) {
case '+':
System.out.println(n + " plus " + p + " is " + (n + p));
run = false;
break;
case '-':
System.out.println(n + " minus " + p + " is " + (n - p));
run = false;
break;
case '*':
System.out
.println(n + " multiplied by " + p + " is " + (n * p));
run = false;
break;
case '/':
System.out.println(n + " divided by " + p + " is " + (n / p)
+ " with remainder " + (n % p));
run = false;
break;
default:
System.out.println("Invalid character");
run = false;
break;
}
String lastInteger = JOptionPane
.showInputDialog("Enter 0 to quit, or any other integer to continue. ");
q = Integer.parseInt(lastInteger);
System.out.println(q);
System.exit(0);
continue;
}
}
Sorry for lack of comments.