I'm going insane..I'm so close to getting this code to work the way I want to I just can't figure it out. I'm trying to solve a postfix equation for ex. 3 2 + , this equals 5. When I put for example
"3 2 +" in the mainmethod it works fine but as soon as I enter a 3rd digit like "3 2 + 2 *" (which equals 10) I get a arrayoutofboundserror relating back to number2 = s.pop() as you will see in the code below. Any help is greatly appreciated.
Heres the postfix meethod:
public int PostfixEvaluate(String e){
int number1;
int number2;
int result=0;
String[] tokens = e.split(" ");
for(int j = 0; j < tokens.length; j++){
String token = tokens[j];
if (!"+".equals(token) && !"*".equals(token) && !"-".equals(token) && !"/".equals(token)) {
s.push(Integer.parseInt(token));
} else {
String Operator = tokens[j];
number1 = s.pop();
number2 = s.pop();
if (Operator.equals("/")){
result = number1 / number2;}
else if(Operator.equals("*")){
result = number1 * number2;}
else if(Operator.equals("+")){
result = number1 + number2;}
else if(Operator.equals("-")){
result = number1 - number2;}
else System.out.println("Illeagal symbol");
}
s.push(result);
s.pop();
}
//s.pop();
System.out.println("Postfix Evauation = " + result);
return result;
}
public static void main(String[] args) {
Stacked st = new Stacked(100);
//String y = new String("((z * j)/(b * 8) ^2");
String x = new String("2 2 2 * +");
TestingClass clas = new TestingClass(st);
//clas.test(y);
clas.PostfixEvaluate(x);
}
}
/**
* Evaluate postfix arithmetic expression
*
* #example "1 12 23 + * 4 5 / -" => 34.2
* #author Yong Su
*/
import java.util.Stack;
class PostfixEvaluation {
public static void main(String[] args) {
String postfix = "1 12 23 + * 4 5 / -";
Double value = evaluate(postfix);
System.out.println(value);
}
/**
* Evaluate postfix expression
*
* #param postfix The postfix expression
*/
public static Double evaluate(String postfix) {
// Use a stack to track all the numbers and temporary results
Stack<Double> s = new Stack<Double>();
// Convert expression to char array
char[] chars = postfix.toCharArray();
// Cache the length of expression
int N = chars.length;
for (int i = 0; i < N; i++) {
char ch = chars[i];
if (isOperator(ch)) {
// Operator, simply pop out two numbers from stack and perfom operation
// Notice the order of operands
switch (ch) {
case '+': s.push(s.pop() + s.pop()); break;
case '*': s.push(s.pop() * s.pop()); break;
case '-': s.push(-s.pop() + s.pop()); break;
case '/': s.push(1 / s.pop() * s.pop()); break;
}
} else if(Character.isDigit(ch)) {
// Number, push to the stack
s.push(0.0);
while (Character.isDigit(chars[i]))
s.push(10.0 * s.pop() + (chars[i++] - '0'));
}
}
// The final result should be located in the bottom of stack
// Otherwise return 0.0
if (!s.isEmpty())
return s.pop();
else
return 0.0;
}
/**
* Check if the character is an operator
*/
private static boolean isOperator(char ch) {
return ch == '*' || ch == '/' || ch == '+' || ch == '-';
}
}
The number1 assignment should be after the number2 assignment. Remember that s.pop() will remove and return the number that is on the top.
number2 = s.pop();
number1 = s.pop();
Are you popping immediately after pushing?
s.push(result);
s.pop();
There is another logical error in this solution. You need to do:
number2 = s.pop();
number1 = s.pop();
your solution won't work if you had 32/ because you will evaluate it to 2/3.
Related
public static void main(String[] args) {
Scanner String = new Scanner(System.in);
System.out.print("Enter a String: ");
String Str1 =String.nextLine();
String input;
input = Str1;
char[] inputArray = input.toCharArray();
String[] lines = new String[input.length() / 2 + 1];
int i, u;
for (i = 0; i < input.length() / 2; i++) {
char begChar = inputArray[i];
char endChar = inputArray[input.length() - i - 1];
int spacesBefore = i;
int spacesAfter = i;
int spacesInBetween = input.length() - 2 - 2 * i;
String line = "";
for (u = 0; u< spacesBefore; u++) {
line += " ";
}
line += begChar;
for (u = 0; u < spacesInBetween; u++) {
line += " ";
}
line += endChar;
lines[i] = line;
}
if (input.length() % 2 != 0) {
String lastLine = "";
for (u = 0; u < input.length() / 2; u++) {
lastLine += " ";
}
lastLine += inputArray[input.length() / 2];
lines[input.length() / 2] = lastLine;
}
for (i = 0; i < lines.length && lines[i] != null; i++) {
System.out.println(lines[i]);
}
System.out.print("String Length: ");
System.out.println(Str1.length());}
This is where I am having the issue with my code.
I am trying to get this to print whether the user entered String is odd or even. Using Netbeans IDE it keeps telling me that I have a bad operand type int for unary operator '!'. Everything else in the code is working like it should just can't get this to work.
if ( !(Str1.length( ) %0x2))
System.out.println("The String is odd");
else
System.out.println("The String is even");
! is an unary negation operator that expects a single boolean operand. Therefore it can't be applied on an int
You should change
if ( !(Str1.length( ) %0x2))
System.out.println("The String is odd");
else
System.out.println("The String is even");
To this
if (Str1.length() %2 != 0){
System.out.println("The String is odd");
}
else{
System.out.println("The String is even");
}
!= is the operator that checks if the values of two operands are equal or not, if values are not equal then condition becomes true.
Basically you do this:
if (Str1.length() %2 != 0)
Currently you are attempting to call the ! operator on a integer result from using the % operator which is producing the error you are seeing currently
if (!(Str1.length( ) % 0x2))
System.out.println("The String is odd");
else
System.out.println("The String is even");
What you can do is what was suggested by others. This works because you are comparing your result of using the % operator with 2 which produces a boolean result. Therefore the if statement can evaluate it and determine it to be true or false. With the added ! operator you reverse the result of whatever the expression is inside the parentheses.
if (!(Str1.length( ) % 2 != 0))
System.out.println("The String is odd");
else
System.out.println("The String is even");
I want to write a program to calculate output given arithmetical expression . Like that:
My input is: * + * + 1 2 + 3 4 5 6
My output should be: 156
I wrote a Java program to do this using Stack data type.
Here is my Java program:
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static void main(String args[]){
Stack stack =new Stack();
String input;
String trimmedInput[];
int output;
int number1,number2;
int countOfNumber,j;
Scanner scanner = new Scanner(System.in);
System.out.println("put your arithmetical expression. Using Space between ");
input=scanner.nextLine();
trimmedInput=input.split("\\s+");
// for(String a:trimmedInput)
// System.out.println(a);
countOfNumber=trimmedInput.length;
for(j=0;j<countOfNumber;j++) {
if (isNumeric(trimmedInput[j])) {
stack.push(trimmedInput[j]);
}
if (trimmedInput[j].equals("+")) {
number1 = Integer.parseInt((String) stack.pop()) ;
number2 = Integer.parseInt((String) stack.pop()) ;
output = number1 + number2;
stack.push(output);
}
if(trimmedInput[j].equals("-")){
number1 = Integer.parseInt((String) stack.pop()) ;
number2 = Integer.parseInt((String) stack.pop()) ;
output = number1-number2;
stack.push(output);
}
if(trimmedInput[j].equals("*")){
number1 = Integer.parseInt((String) stack.pop()) ;
number2 = Integer.parseInt((String) stack.pop()) ;
output = number1*number2;
stack.push(output);
}
if(trimmedInput[j].equals("/")){
number1 = Integer.parseInt((String) stack.pop()) ;
number2 = Integer.parseInt((String) stack.pop()) ;
output = number1/number2;
stack.push(output);
}
}
while(!stack.isEmpty())
System.out.println(stack.pop());
}
public static boolean isNumeric(String str)
{
try
{
double d = Double.parseDouble(str);
}
catch(NumberFormatException nfe)
{
return false;
}
return true;
}
}
Ok. Here is my problem. If I want to calculate * + * + 1 2 + 3 4 5 6 something like that, my compiler gives an error like that:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:102)
at java.util.Stack.pop(Stack.java:84)
at Main.main(Main.java:41)
Here is my 41. row at code:
number1 = Integer.parseInt((String) stack.pop()) ;
I cannot figured out what is problem in my code. I'm new at Java. Please help me. Thanks a lot :)
Your code is giving you error because you are parsing from left-to-right. So the first string it gets is "*" - star. So, it checks that it's a star, and pops from the stack. But, the stack is empty!! So, you should traverse from right-to-left and when you find number push into stack, and when you find an operator, do the operation
for (int i = trimmedInput.length-1; i >= 0; i--) {
if (isNumeric(trimmedInput[i])) stack.push(trimmedInput[i]);
else if (trimmedInput[i].equals("*")) {
// here you might get StackEmptyException if your expression is invalid
// if you want to avoid that, then use try-catch and throw your custom InvalidExpressionExceptiono
number1 = Integer.parseInt((String)stack.pop());
number2 = Integer.parseInt((String)stack.pop());
output = number1*number2;
stack.push(output);
}
.
.
. // do the same for other operators
.
.
}
Updated answer
Shouldn't you push all operators into the stack, and pop it out after you see two operands ? (You will have two operands when one is at the top of the stack, and the other just comes in i.e. trimmedInput[j]).
Alternative solution for above problem ..
import java.util.Scanner;
import java.util.Stack;
public class Expression
{
static int i = 0 ;
static Stack stack = new Stack<>();
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String input = in.next();
input += in.nextLine();
char expr[] = input.toCharArray();
for(int j = expr.length-1 ; j>=0 ; j--)
{
stack.push(process(expr[j]));
}
System.out.println("Result is : " + stack.pop());
}
public static int process(char val)
{
int res = val;
int flag = 0;
if(val == '+')
{
flag = 1 ;
res = (Integer)stack.pop() + (Integer)stack.pop();
}
else if(val == '-')
{
flag =1 ;
res = (Integer)stack.pop() - (Integer)stack.pop();
}
else if(val == '*')
{
flag =1 ;
res = (Integer)stack.pop() * (Integer)stack.pop();
}
else if(val == '/')
{
flag =1 ;
res = ((Integer)stack.pop() / (Integer)stack.pop());
}
if(flag == 1)
return res;
else
return res-48;
}
public static void print()
{
int k = i;
while(--k >= 0)
{
System.out.print(stack.peek() + " : ");
}
System.out.println("\n");
}
}
private class InputListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
// Create an integer and character stack
Stack<Integer> operandStack = new Stack<Integer>();
Stack<Character> operatorStack = new Stack<Character>();
// User input in input text field
String input = inputTextField.getText();
// Create string tokenizer containing string input
StringTokenizer strToken = new StringTokenizer(input);
// Loop while there are tokens
while (strToken.hasMoreTokens())
{
String i = strToken.nextToken();
int operand;
char operator;
try
{
operand = Integer.parseInt(i);
operandStack.push(operand);
}
catch (NumberFormatException nfe)
{
operator = i.charAt(0);
operatorStack.push(operator);
}
}
// Loop until there is only one item left in the
// operandStack. This one item left is the result
while(operandStack.size() > 1)
{
// Perform the operations on the stack
// and push the result back onto the operandStack
operandStack.push(operate(operandStack.pop(),
operandStack.pop(), operatorStack.pop()));
}
// Display the result as a string in the result text field
resultTextField.setText(Integer.toString(operandStack.peek()));
}
// Sum and product computed
public int operate(Integer operand1, Integer operand2, char operator)
{
switch(operator)
{
case '*':
return operand2 * operand1;
case '/':
return operand2 / operand1;
case '%':
return operand2 % operand1;
case '+':
return operand2 + operand1;
case '-':
return operand2 - operand1;
default:
throw new IllegalStateException("Unknown operator " + operator + " ");
}
}
}
The prefix expression code provided is incorrectly evaluating expressions with more than one operator. The expression: * + 16 4 + 3 1 should evaluate to 80 = ((16 + 4) * (3 + 1)), but instead it evaluates to 128, which I think is evaluating as: ((16 + 4) * (3 + 1) + (16 * 3)). How do I edit the code to correct this problem? Thank you for your help.
In prefix evaluation,Important thing to remember is
operand 1= pop();
operand 2= pop();
and say the operator is -
The value that is pushed is operand 1 - operand 2 and not operand 2 - operand 1
But something else is causing * + 16 4 + 3 1 to evaluate to 128.
I used the following algo for evaluating in java and it works fine
1.Take the prefix expression as a string in a variable with characters separated by single space.
2.Traverse the string from index length-1 to 0
3.If its a number, perform push ,and if its a multidigit number,first obtain the full number and then push it
4.If its an operator then simply do the thing which i mentioned in beginning of the answer.
It is a simple code.
import java.io.*;
import java.util.*;
class PREFIXEVAL
{
public static void main(String []args)throws IOException
{
String p,n="";StringBuffer b;int i,op1,op2;char c;Stack<Integer> s=new Stack<Integer>();
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
System.out.println("enter the prefix expression separated by spaces");
p=br.readLine();
i=p.length()-1;
while(i>=0)
{
c=p.charAt(i);
if(c>=48&&c<=57)
n=n+c;
else if(c==' '&&!n.equals(""))
{/*handles both single and multidigit numbers*/
b=new StringBuffer(n);b.reverse();n=b.toString();
s.push(Integer.parseInt(n));n="";
}
else
{
if(c=='+')
{
op1=s.pop();
op2=s.pop();
s.push(op1+op2);
}
else if(c=='-')
{
op1=s.pop();
op2=s.pop();
s.push(op1-op2);
}
else if(c=='*')
{
op1=s.pop();
op2=s.pop();
s.push(op1*op2);
}
else if(c=='%')
{
op1=s.pop();
op2=s.pop();
s.push(op1%op2);
}
else if(c=='/')
{
op1=s.pop();
op2=s.pop();
s.push(op1/op2);
}
}
i--;
}
System.out.println("the prefix expression evaluates to "+s.peek());
}
}
I'm trying to learn Java, but I'm struggling a little bit. I'm trying to do an assignment from a textbook, so I did it in javascript and was using my limited knowledge of Java to convert it over. (Here's the original instructions - http://i518.photobucket.com/albums/u341/ACrippledFerret/5ea8ec0e-02aa-4b96-b207-a83c52f8db48_zps2cd2ab7f.jpg)
I think I've got most of it correct, but I'm running into a couple of errors. Almost all of it is "(variable) cannot be resolved to a variable". It happens to lots of variables in my last method. I also seem to have an issue with a bracket somewhere... "Syntax error on token "}", { expected after this token".
If anyone can help fix this code, I would be very grateful. I am new to Java so this is a bit tough for me to translate. The first set of code is the javascript, the second set of code is my translated java (That's not working). Thanks for any help.
JAVASCRIPT
window.onload=function(){
var difficulty = 1,
operators = ['plus', 'minus', 'times', 'divided by'],
selectedOperator = 1,
correctAnswers = 0,
answeredTyped = 0;
var difficultyInput = parseInt(prompt('Please choose the difficulty. Enter the number of digits to use in each problem.'), 10);
if(difficultyInput > 0) {
difficulty = difficultyInput;
}
var arithmeticMethod = parseInt(prompt('Choose an arithmetic problem to study:\n1 = Addition Only\n2 = Subtraction Only\n3 = Multiplication Only\n4 = Division Only\n5 = Random Problems'), 10);
if(arithmeticMethod == 5 || operators[arithmeticMethod - 1]) {
selectedOperator = arithmeticMethod;
}
function checkResponse(primaryInt, secondaryInt, operatorText, suggestedAnswer) {
var result = false;
switch (operatorText) {
case 'plus':
return (primaryInt + secondaryInt) == suggestedAnswer;
case 'minus':
return (primaryInt - secondaryInt) == suggestedAnswer;
case 'times':
return (primaryInt * secondaryInt) == suggestedAnswer;
case 'divided by':
return (primaryInt / secondaryInt) == suggestedAnswer;
default:
return false;
}
}
function displayResponse(isCorrect) {
var randomIndex = Math.floor(Math.random() * (4 - 1 + 1)) + 1;
switch (randomIndex) {
case 1:
return isCorrect ? 'Very good!' : 'No. Please try again.';
case 2:
return isCorrect ? 'Excellent!' : 'Wrong. Try once more.';
case 3:
return isCorrect ? 'Nice Work!' : 'Don\'t give up!';
case 4:
return isCorrect ? 'Keep up the good work!' : 'No. Keep trying.';
default:
return 'Woops...';
}
}
function askQuestion() {
var correctAnswer = false;
var primaryInt = Math.floor(Math.pow(10, difficulty-1) + Math.random() * 9 * Math.pow(10, difficulty-1));
secondaryInt = Math.floor(Math.pow(10, difficulty-1) + Math.random() * 9 * Math.pow(10, difficulty-1));
operatorText = (selectedOperator == 5) ? operators[Math.floor(Math.random() * operators.length)] : operators[selectedOperator - 1];
while(!correctAnswer && answeredTyped < 10) {
var response = parseFloat(prompt('How much is ' + primaryInt + ' ' + operatorText + ' ' + secondaryInt + '?'));
correctAnswer = checkResponse(primaryInt, secondaryInt, operatorText, response);
alert(displayResponse(correctAnswer));
answeredTyped++;
if(correctAnswer)
correctAnswers++;
}
}
while(answeredTyped < 10) {
askQuestion();
}
if((correctAnswers / answeredTyped) >= 0.75) {
alert('Congratulations, you are ready to go on the next level!');
} else {
alert('Please ask your teacher for extra help.');
}
}
JAVA
import java.util.*;
import javax.swing.JOptionPane;
/**
*
*/
/**
* #author Tyler
*
*/
public class Assignment2 {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner input = new Scanner(System.in);
int difficulty = 1;
String[] operators = {"plus", "minus", "times", "divided by"};
int selectedOperator = 1;
int correctAnswers = 0;
int answeredTyped = 0;
int difficultyInput = Integer.parseInt(JOptionPane.showInputDialog("Please choose the difficulty. Enter the number of digits to use in each problem."));
if (difficultyInput > 0) {
difficulty = difficultyInput;
}
int arithmeticMethod = Integer.parseInt(JOptionPane.showInputDialog("Choose an arithmetic problem to study: 1 = Addition Only, 2 = Subtraction Only, 3 = Multiplication Only, 4 = Division Only, 5 = Random Problems" ));
selectedOperator = arithmeticMethod;
}
public static boolean checkResponse (double primaryInt, double secondaryInt, String operatorText, float response){
boolean result = false;
switch (operatorText){
case "1":
return (primaryInt + secondaryInt) == response;
case "2":
return (primaryInt - secondaryInt) == response;
case "3":
return (primaryInt * secondaryInt) == response;
case "4":
return (primaryInt / secondaryInt) == response;
}
return false;
}
public static String displayResponse (boolean isCorrect){
int randomIndex = (int) (Math.floor(Math.random() * (4 - 1 + 1)) + 1);
switch (randomIndex){
case 1:
return isCorrect ? "Very Good!" : "No. Please try again.";
case 2:
return isCorrect ? "Excellent!" : "Wrong. Try once more.";
case 3:
return isCorrect ? "Nice Work!" : "Don\'t give up!";
case 4:
return isCorrect ? "Keep up the good work!" : "No. Keep trying.";
}
return "Oops...";
}
public static void askQuestion(int difficulty, String operatorText, int selectedOperator, int answeredTyped, String[] operators, int correctAnswers){
boolean correctAnswer = false;
double primaryInt = Math.floor(Math.pow(10, difficulty-1) + Math.random() * 9 * Math.pow(10, difficulty-1));
double secondaryInt = Math.floor(Math.pow(10, difficulty-1) + Math.random() * 9 * Math.pow(10, difficulty-1));
operatorText = (selectedOperator == 5) ? operators[(int) Math.floor(Math.random() * operators.length)] : operators[selectedOperator - 1];
while(!correctAnswer && answeredTyped < 10) {
float response = Float.parseFloat (JOptionPane.showInputDialog("How much is " + primaryInt + " " + operatorText + " " + secondaryInt + "?"));
correctAnswer = checkResponse (primaryInt, secondaryInt, operatorText, response);
JOptionPane.showMessageDialog(null, displayResponse(correctAnswer));
answeredTyped++;
if(correctAnswer)
correctAnswers++;
}
{
while(answeredTyped < 10){
askQuestion(0, null, 0, 0, null, 0);
}
if((correctAnswers / answeredTyped) >= 0.75) {
JOptionPane.showMessageDialog(null, "Congratulations, you are ready to go on to the next level!");
}
else{
JOptionPane.showMessageDialog(null, "Please ask your teacher for extra help.");
}
}
}
}
The scoping is different in Java than in Javascript; Java variables defined in a method (static or instance) will be valid only within that method, so you can't reference variables such as difficulty (defined in main()) from other methods such as askQuestion(). You could make them static class member variables, but that's generally bad practice in Java (and also in Javascript, really), so the better option is to pass them into methods such as askQuestion() as arguments to the method.
i would like to include a simple RPN type calculator function in one of my projects.
basically i need a method that can convert for example:
"30 / ((1 + 4) * 3)" into "2"
does anyone know of any pre-written libs that can do this?
thanks.
You should implement Shunting Yard Algorithm
also look : Reverse Polish notation
You can use Shunting Yard (Jep API)
I suggest you to write it in python if you don't have to implement it in Java because of it's built-in methods
print eval("30 / ((1 + 4) * 3)")
ideone demo
You need a parser and a stack.
Google brought back a bunch of links. I can't recommend any of them, because none of my apps require an RPN calculator.
If this is homework, please mark it as such.
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
import java.util.Stack;
public class Rpncalculator
{
static final HashMap<String, Integer> prec;
static
{
prec = new HashMap<>();
prec.put("^", 3);
prec.put("%", 2);
prec.put("*", 2);
prec.put("/", 2);
prec.put("+", 1);
prec.put("-", 1);
}
public static void main(String[] args)
{
Queue<String> infixQueue = new LinkedList<>(); //Standard Queue class provided by Java Framework.
Scanner sc = new Scanner(System.in);
Double number = 0.0;
Character c, cNext = ' ';
String input;
String multiDigit = "";
do
{
System.out.println("Enter your INFIX expression or 'quit' to exit: ");
input = sc.nextLine();
input = input.replaceAll(" ", ""); //ignore spaces in input infix expression
if (input.equals("quit"))
{
System.exit(0);
}
for (int i = 0; i < input.length(); i++)
{
c = input.charAt(i);
if (i + 1 < input.length())
{
cNext = input.charAt(i + 1);
}
if (c.equals('(') || c.equals(')'))
{
if (c.equals('(') && cNext.equals('-'))
{
System.out.println("NEGATIVE Numbers not allowed");
main(args);
// System.exit(0);
} else
{
infixQueue.add(c.toString());
}
} else if (!Character.isDigit(c))
{
if (infixQueue.isEmpty() && c.equals('-'))
{
System.out.println("NEGATIVE Numbers not allowed");
main(args);
} else if (cNext.equals('-'))
{
System.out.println("NEGATIVE Numbers not allowed");
main(args);
} else
{
infixQueue.add(c.toString());
}
} else if (Character.isDigit(c))
{
if (i + 1 < input.length() && input.charAt(i + 1) == '.') //to handle decimal
{
int j = i + 1;
multiDigit = c.toString() + input.charAt(j); //to handle multidigit
while (j + 1 <= input.length() - 1 && Character.isDigit(input.charAt(j + 1)))
{
multiDigit = multiDigit + input.charAt(j + 1);
j++;
}
i = j;
infixQueue.add(multiDigit);
multiDigit = "";
} else if (i + 1 <= input.length() - 1 && Character.isDigit(input.charAt(i + 1)))
{
int j = i;
//multiDigit=c.toString()+input.charAt(i);
while (j <= input.length() - 1 && Character.isDigit(input.charAt(j)))
{
multiDigit = multiDigit + input.charAt(j);
j++;
}
i = j - 1;
infixQueue.add(multiDigit);
multiDigit = "";
} else
{
infixQueue.add(c.toString());
}
}
}
infixToPostfix(infixQueue);
} while (!input.equals("quit"));
}
//method to convert from infix to postfix
public static void infixToPostfix(Queue<String> infixQueue)
{
Stack operatorStack = new Stack();
Queue<String> postQueue = new LinkedList<>();
String t;
while (!infixQueue.isEmpty())
{
t = infixQueue.poll();
try
{
double num = Double.parseDouble(t);
postQueue.add(t);
} catch (NumberFormatException nfe)
{
if (operatorStack.isEmpty())
{
operatorStack.add(t);
} else if (t.equals("("))
{
operatorStack.add(t);
} else if (t.equals(")"))
{
while (!operatorStack.peek().toString().equals("("))
{
postQueue.add(operatorStack.peek().toString());
operatorStack.pop();
}
operatorStack.pop();
} else
{
while (!operatorStack.empty() && !operatorStack.peek().toString().equals("(") && prec.get(t) <= prec.get(operatorStack.peek().toString()))
{
postQueue.add(operatorStack.peek().toString());
operatorStack.pop();
}
operatorStack.push(t);
}
}
}
while (!operatorStack.empty())
{
postQueue.add(operatorStack.peek().toString());
operatorStack.pop();
}
System.out.println();
System.out.println("Your POSTFIX expression is: ");
//numbers and operators all seperated by 1 space.
for (String val : postQueue)
{
System.out.print(val + " ");
}
postfixEvaluation(postQueue);
}
//method to calculate the reuslt of postfix expression.
public static void postfixEvaluation(Queue<String> postQueue)
{
Stack<String> eval = new Stack<>(); //Standard Stack class provided by Java Framework.
String t;
Double headNumber, nextNumber, result = 0.0;
while (!postQueue.isEmpty())
{
t = postQueue.poll();
try
{
double num = Double.parseDouble(t);
eval.add(t);
} catch (NumberFormatException nfe)
{
headNumber = Double.parseDouble(eval.peek());
eval.pop();
nextNumber = Double.parseDouble(eval.peek());
eval.pop();
switch (t)
{
case "+":
result = nextNumber + headNumber;
break;
case "-":
result = nextNumber - headNumber;
break;
case "*":
result = nextNumber * headNumber;
break;
case "/":
//in java, there is no exception generated when divided by zero and thus checking
//for
if (headNumber == 0)
{
System.out.println("\nERROR: Cannot Divide by zero!\n");
return;
} else
{
result = nextNumber / headNumber;
break;
}
case "%":
result = nextNumber % headNumber;
break;
case "^":
result = Math.pow(nextNumber, headNumber);
break;
}
eval.push(result.toString());
}
}
System.out.println("\nRESULT is: ");
DecimalFormat df = new DecimalFormat("0.000");
for (String val : eval)
{
System.out.println(df.format(Double.parseDouble(val)) + "\n");
}
}
}
Actually, this is not an "RPN" question, because you want to evaluate an algebraic expression.
7th is primarily a RPN language, but can evaluate algebraic expressions with the restriction that they must not contain spaces and must be enclosed in round braces:
private static final ScriptEngineManager mgr = new ScriptEngineManager();
private static final ScriptEngine engine = mgr.getEngineByName( "7th" );
…
try {
Number d;
d = (Number)engine.eval( "(30/((1+4)*3))" ); // 2.0
d = (Number)engine.eval( "30 1 4 + 3 * /" ); // 2.0
}
catch( ScriptException ex ) {
ex.printStackTrace();
}