Logical error using a stack to evaluate a postfix - java

Hello I am getting a logical error where it isn't saluting the postfix correctly. For example:
-16.0
16.01171875
-16.25
I do not know why am getting negative numbers It is supposed to be:
25.0
9.71
17.0
I think Im doing the pushing wrong but I don't know where it could be wrong. Here's the method:
static double evaluatePostfix(String postfix){
Stack stack = new Stack();
int size =postfix.length();
for(int i = 0; i<postfix.length(); i++){
if(postfix.charAt(i) == '+'|| postfix.charAt(i) == '-'||postfix.charAt(i) == '*'||postfix.charAt(i) == '/'){
double value =0 ;
double value2 = 0 ;
String str = stack.pop().toString();
String str2 = stack.pop().toString();
value = Double.valueOf(str).doubleValue();
value2 = Double.valueOf(str2).doubleValue();
switch(postfix.charAt(i))
{
case '+': stack.push(value2 + value);
break;
case '-': stack.push(value2 - value);
break;
case '*': stack.push(value2 * value );
break;
case '/': stack.push(value2 / value);
break;
}
}
else if (postfix.charAt(i) >= 'a' && postfix.charAt(i) <= 'z'){
System.out.println("bad Character");
return Double.NEGATIVE_INFINITY;
}
else{
double operand = (double)(postfix.charAt(i) - '0');
stack.push(operand);
size++;
}
}
return (double)(stack.pop());
}
I have to convert the popping into doubles because I can't create a double stack and I must use a stack class instead without importing any java.utils.
Here's the stack class
public class Stack{
private Node top;
public Stack() {
top = null;
}
public boolean isEmpty(){
return (top ==null);
}
public void push(Object newItem){
top = new Node(newItem, top);
}
public Object pop(){
if (isEmpty()){
System.out.println(
"Trying to pop when stack is empty");
return null;
}else{
Node temp = top;
top = top.next;
return temp.info;
}
}
void popAll(){
top = null;
}
public Object peek(){
if (isEmpty()){
System.out.println(
"Trying to peek when stack is empty");
return null;
}else{
return top.info;
}
}
Here's the input:
10 2 / 5 *
5 10 - 3 9 - * 5 4 - 4 2 / + / 2 27 + 300 3 / / -
15 8 4 / +

Related

How to properly evaluate postfix notations in java?

I've already made my code and it's working for some cases and isn't for other cases. It's hard to solve the level of precedence because of its complexity especially when it comes to relational and logical operators. I can already successfully convert infix to postfix notation but can't successfully evaluate the postfix.
import java.util.*;
import java.lang.Character;
public class PostEvaluator
{
private Stack stack;
private Queue queue;
public PostEvaluator()
{
stack = new Stack(256);
queue = new Queue();
}
//this function will check if the character being checked is an operator or not
private static boolean isOperator(String c)
{
if (!Character.isLetterOrDigit(c.charAt(0)))
return true;
else
return false;
}
//this function will calculate the necessary calculation needed
private int operate (int x, int y, String operator)
{
int result = 0;
switch (operator)
{
case "*":
result = x * y;
break;
case "/":
if (y != 0)
result = x / y;
else
{
System.out.println("Division by zero error!");
System.exit(0);
}
break;
case "+":
result = x + y;
break;
case "-":
result = x - y;
break;
case "%":
result = x % y;
break;
case "^":
result = x ^ y;
break;
case ">":
if (x > y)
return 1;
else
return 0;
case "<":
if (x < y)
return 1;
else
return 0;
case ">=":
if (x >= y)
return 1;
else
return 0;
case "<=":
if (x <= y)
return 1;
else
return 0;
case "!=":
if (x != y)
return 1;
else
return 0;
case "==":
if (x == y)
return 1;
else
return 0;
case "&&":
result = x & y;
break;
case "||":
result = x | y;
break;
}
return result;
}
private int notOperate (int x)
{
if (x == 0)
return 1;
else
return 0;
}
//this function will evaluate the post fix
public String evaluatePostFix(String input)
{
String val1, val2, result = "", temp;
int intVal1, intVal2;
Scanner kb = new Scanner(input);
//splits the input by operand
kb.useDelimiter(" ");
do
{
queue.enqueue(kb.next());
} while (kb.hasNext());
do
{
//assign the temp of the first data in the queue
temp = (String) queue.dequeue();
if (!(temp.equals("")))
{
//if the value is not an operator, push it to the stack
if (!isOperator(temp)) {
stack.push(temp);
}
else
{
if (!stack.isEmpty())
{
if (!(temp.equals("!")))
{
//assign the val 1 the last item in the stack to be evaluated
val1 = (String) stack.pop();
if (!stack.isEmpty()) {
val2 = (String) stack.pop();
intVal1 = Integer.parseInt(val1);
intVal2 = Integer.parseInt(val2);
result = Integer.toString(operate(intVal2, intVal1, temp));
stack.push(result);
}
else
{
System.out.println("Missing Operand/s Error");
System.exit(0);
}
}
else
{
val1 = (String) stack.pop();
intVal1 = Integer.parseInt(val1);
result = Integer.toString(notOperate (intVal1));
stack.push(result);
}
}
else
{
System.out.println("Missing Operand/s Error");
System.exit(0);
}
}
if (result.equals(""))
result = temp;
}
}while (!queue.isEmpty());
return result;
}
}
I've only seen postfix evaluation for arithmetic expressions without relational and logical operators

How to do different traversals of an expression tree?

I'm trying to figure out how to do the different traversals through an expression tree. For example, if I type in " - + 10 * 2 8 3 ", I want it to print out the prefix, postfix, and infix versions of that expression.
I also need to calculate the result of the expression through a postorder traversal, which should be the evaluate function.
However, when I run my program, I only get the first character of each expression. Is my understanding of how these traversals work wrong?
EDIT: Following suggestions, I saved the result of the buildtree and also changed sc.next to sc.nextLine.
Also, every method should be recursive.
Given "- + 10 * 2 8 3", the expected answer would be:
prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
( ( 10 + ( 2 * 8 ) ) - 3 )
Result = 23
I understand I haven't implemented anything with parentheses for the infix expression, but that's okay for now.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.print("Enter a prefix expression: ");
Node root = buildTree(sc);
System.out.println("prefix expression: ");
infix(root);
System.out.println("postfix expression: ");
postfix(root);
System.out.println("infix expression: ");
infix(root);
System.out.print("Result = ");
evaluate(root);
}
static Node buildTree(Scanner sc) {
Node n = new Node(null);
int i = 0;
String prefixExpression = sc.nextLine();
String[] temp = prefixExpression.split(" ");
if(n.isLeaf()) {
n.value = temp[i];
n.left = null;
n.right = null;
i++;
}
return n;
}
static void infix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
infix(node.left);
System.out.println(node.value + " ");
infix(node.right);
}
}
void prefix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
switch(node.value) {
case "+":
System.out.print("+");
break;
case "-":
System.out.print("-");
break;
case "*":
System.out.print("*");
break;
case "/":
System.out.print("/");
break;
}
}
prefix(node.left);
System.out.print(" ");
prefix(node.right);
}
static void postfix(Node node) {
if(node.isLeaf()){
System.out.println(node.value);
}
else {
postfix(node.left);
postfix(node.right);
switch (node.value) {
case "+":
System.out.print("+");
break;
case "-":
System.out.print("-");
break;
case "*":
System.out.print("*");
break;
case "/":
System.out.print("/");
break;
}
}
}
public static int evaluate(Node node) {
if(node.isLeaf()) {
return Integer.parseInt(node.value);
}
else {
int leftHandSide = evaluate(node.getLeft());
int rightHandSide = evaluate(node.getRight());
String operator = node.getValue();
if("+".equals(operator)) {
return leftHandSide + rightHandSide;
}
else if("-".equals(operator)) {
return leftHandSide - rightHandSide;
}
else if("*".equals(operator)) {
return leftHandSide * rightHandSide;
}
else if("/".equals(operator)) {
return leftHandSide / rightHandSide;
}
else {
System.out.println("Unexpected problem. Error.");
}
return 0;
}
}
}
Here is Node.java, There's getters and setters too.
public class Node<E> {
String value;
Node<E> left;
Node<E> right;
Node(String value){
left = null;
right = null;
this.value = value;
}
Node(String value, Node<E> left, Node<E> right) {
this.value = value;
this.left = left;
this.right = right;
}
boolean isLeaf() {
return (left == null && right == null);
}
EDIT:
Since your question says "How to do different traversals of an expression tree?, The problem I can see in your code is building the tree ( i.e. buildTree() method).
In order to correct this, I have used buildExpressionTree(array) method to convert your prefix input to an expression tree using Stack data structure.
Construction of Expression Tree:
For constructing expression tree I have use a stack. Since in your case input is in prefix form so Loop in reverse through input expression and do following for every character.
If character is operand push that into stack
If character is operator pop two values from stack make them its
child and push current node again.
At the end only element of stack will be root of expression tree.
Also while printing different traversals, you do not need all those if conditions to check for different operators.You can simply do the traversal as shown in my code below.
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a prefix expression: ");
String prefixExpression = sc.nextLine();
String[] temp = prefixExpression.split(" ");
Node n = null;
n = buildExpressionTree(temp);
System.out.println("prefix expression: ");
prefix(n);
System.out.println();
System.out.println("postfix expression: ");
postfix(n);
System.out.println();
System.out.println("infix expression: ");
infix(n);
System.out.println();
int result = evaluate(n);
System.out.print("Result = "+ result);
}
static Node buildExpressionTree(String[] input) {
Stack<Node> st = new Stack();
Node t, t1, t2;
// Traverse through every character of
// input expression
for (int i = (input.length-1); i >= 0; i--) {
// If operand, simply push into stack
if (isNumber(input[i])) {
t = new Node(input[i]);
st.push(t);
} else // operator
{
t = new Node(input[i]);
// Pop two top nodes
// Store top
t1 = st.pop(); // Remove top
t2 = st.pop();
// make them children
t.left = t1;
t.right = t2;
st.push(t);
}
}
t = st.peek();
st.pop();
return t;
}
static boolean isNumber(String s) {
boolean numeric = true;
try {
Integer num = Integer.parseInt(s);
} catch (NumberFormatException e) {
numeric = false;
}
return numeric;
}
static void infix(Node node) {
if( null == node) {
return;
}
infix(node.left);
System.out.print(node.value + " ");
infix(node.right);
}
static void prefix(Node node) {
if( null == node) {
return;
}
System.out.print(node.value+ " ");
prefix(node.left);
prefix(node.right);
}
static void postfix(Node node) {
if( null == node) {
return;
}
postfix(node.left);
postfix(node.right);
System.out.print(node.value+ " ");
}
public static int evaluate(Node node) {
if(node.isLeaf()) {
return Integer.parseInt(node.value);
}
else {
int leftHandSide = evaluate(node.left);
int rightHandSide = evaluate(node.right);
String operator = node.value;
if("+".equals(operator)) {
return leftHandSide + rightHandSide;
}
else if("-".equals(operator)) {
return leftHandSide - rightHandSide;
}
else if("*".equals(operator)) {
return leftHandSide * rightHandSide;
}
else if("/".equals(operator)) {
return leftHandSide / rightHandSide;
}
else {
System.out.println("Unexpected problem. Error.");
}
return 0;
}
}
OUTPUT:
Enter a prefix expression:
- + 10 * 2 8 3
prefix expression:
- + 10 * 2 8 3
postfix expression:
10 2 8 * + 3 -
infix expression:
10 + 2 * 8 - 3
Result = 23

File reading error with postfix calculator

I made a postfix calculator and I'm pretty sure it works however it as a reading error. The calculator is designed to read numbers in postfix notation from a line in a file and calc them. However it doesn't recognize lines, for example if I have two lines it will combine the two expressions. I have trouble with file reading so any help would be appreciated. Sorry for any format problem this is my first post. So here is my code so my issue is better understood.
import java.io.*;
import java.util.*;
import java.nio.charset.Charset;
public class PostfixCalculator {
private static final String ADD = "+";
private static final String SUB = "-";
private static final String MUL = "*";
private static final String DIV = "/";
private static final String EXP = "^";
private static final String NEG = "_"; //unary negation
private static final String SQRT = "#";
public void calculateFile(String fileName) throws IOException {
BufferedReader br = null;
StringBuilder sb = null;
try {
FileReader fileReader = new FileReader(fileName);
br = new BufferedReader(fileReader);
sb = new StringBuilder();
String line = br.readLine();
while (line != null) {
sb.append(line);
line = br.readLine();
}
String input = sb.toString();
System.out.println(input + " = " + calculate(input));
} catch (IOException e) {
e.printStackTrace();
} finally {
br.close();
}
}
private double calculate(String input) {
SinglyLinkedListStack<Double> stack = new SinglyLinkedListStack<Double>();
String[] inputs = input.split(" ");
return handleCalculation(stack, inputs);
}
private static double handleCalculation(SinglyLinkedListStack<Double> stack, String[] el) {
double operand1, operand2;
for(int i = 0; i < el.length; i++) {
if( el[i].equals(ADD) || el[i].equals(SUB) || el[i].equals(MUL) || el[i].equals(DIV)||el[i].equals(EXP)||el[i].equals(NEG)||el[i].equals(SQRT)) {
operand2 = stack.pop();
operand1 = stack.pop();
switch(el[i]) {
case ADD: {
double local = operand1 + operand2;
stack.push(local);
break;
}
case SUB: {
double local = operand1 - operand2;
stack.push(local);
break;
}
case MUL: {
double local = operand1 * operand2;
stack.push(local);
break;
}
case DIV: {
double local = operand1 / operand2;
stack.push(local);
break;
}
case EXP: {
double local = Math.pow(operand1, operand2);
stack.push(local);
break;
}
case NEG: {
double local = -(operand1);
stack.push(local);
break;
}
case SQRT:{
double local = Math.pow(operand1, .5);
stack.push(local);
break;
}
}
} else {
stack.push(Double.parseDouble(el[i]));
}
}
return (double)stack.pop();
}
}
This is my linked list
public class SinglyLinkedListStack<T> {
private int size;
private Node<T> head;
public SinglyLinkedListStack() {
head = null;
size = 0;
}
public void push(double local) {
if(head == null) {
head = new Node(local);
} else {
Node<T> newNode = new Node(local);
newNode.next = head;
head = newNode;
}
size++;
}
public T pop() {
if(head == null)
return null;
else {
T topData = head.data;
head = head.next;
size--;
return topData;
}
}
public T top() {
if(head != null)
return head.data;
else
return null;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0;
}
private class Node<T> {
private T data;
private Node<T> next;
public Node(T data) {
this.data = data;
}
}
}
This is my demo
import java.io.IOException;
public class PostFixCalculatorDemo {
public static void main(String[] args) throws IOException {
PostfixCalculator calc = new PostfixCalculator();
calc.calculateFile("in.dat");
}
}
The text file contains
2 3 ^ 35 5 / -
1 2 + 3 * # 4 - 5 6 - + _
my output is 2 3 ^ 35 5 / -1 2 + 3 * # 4 - 5 6 - + _ = -8.0
as it is seen it is combining the two lines. I want it to read the two lines separately and calculate 2 3 ^ 35 5 / - and 1 2 + 3 * # 4 - 5 6 - + _ without putting it together. I know it does this because I programmed the calculateFile class wrong but I am not sure how to fix this without breaking my program.
while (line != null) {
sb.append(line);
line = br.readLine();
}
Basically you are reading every line and appending it to a single Stringbuffer which will result in concatenation of every line from your file. This buffer wont contain newline character or any other sign where your lines end.
From the documentation:
readline:
Reads a line of text. A line is considered to be terminated by any one of a line feed ('\n'), a carriage return ('\r'), or a carriage return followed immediately by a linefeed.
Returns: A String containing the contents of the line, not including
any line-termination characters, or null if the end of the stream has
been reached Throws:
I advice adding the lines to an ArrayList if you are planning to read everything at once.

Conversion of an infix operation to a postfix operation

The code takes in an infix operation and converts it to a postfix operation. I have been able to to the conversion. The problem I'm facing is the spacing between operators. Also, I'd like to know how the postfix operation can be evaluated.
import java.io.IOException;
public class InToPost {
private Stack theStack;
private String input;
private String output = "";
public InToPost(String in) {
input = in;
int stackSize = input.length();
theStack = new Stack(stackSize);
}
public String doTrans() {
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);
switch (ch) {
case '+':
case '-':
gotOper(ch, 1);
break;
case '*':
case '/':
case '%':
gotOper(ch, 2);
break;
case '(':
theStack.push(ch);
break;
case ')':
gotParen(ch);
break;
default:
output = output + ch;
break;
}
}
while (!theStack.isEmpty()) {
output = output + theStack.pop();
}
System.out.println(output);
return output;
}
public void gotOper(char opThis, int prec1) {
while (!theStack.isEmpty()) {
char opTop = theStack.pop();
if (opTop == '(') {
theStack.push(opTop);
break;
}
else {
int prec2;
if (opTop == '+' || opTop == '-')
prec2 = 1;
else
prec2 = 2;
if (prec2 < prec1) {
theStack.push(opTop);
break;
}
else
output = output + opTop;
}
}
theStack.push(opThis);
}
public void gotParen(char ch){
while (!theStack.isEmpty()) {
char chx = theStack.pop();
if (chx == '(')
break;
else
output = output + chx;
}
}
public static void main(String[] args)
throws IOException {
String input = "13 + 23 - 42 * 2";
String output;
InToPost theTrans = new InToPost(input);
output = theTrans.doTrans();
System.out.println("Postfix is " + output + '\n');
}
class Stack {
private int maxSize;
private char[] stackArray;
private int top;
public Stack(int max) {
maxSize = max;
stackArray = new char[maxSize];
top = -1;
}
public void push(char j) {
stackArray[++top] = j;
}
public char pop() {
return stackArray[top--];
}
public char peek() {
return stackArray[top];
}
public boolean isEmpty() {
return (top == -1);
}
}
}
The postfix output for this is:
13 23 + 42 2*-
whereas I am trying to get an output that looks like this:
13 23 + 42 2 * -
I am unable to space the operator in the output.

Getting wrong output for infix/postfix in java using stacks [duplicate]

This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
For input (1+3)*(1+3) I'm getting 1 3 + * 1 3 + for output, when it should be 1 3 + 1 3 + *. I have debugged and cannot figure out why multiplication does not hold until the end. Am I not comparing it the right way in checkOp()?
public String infixToPostfix() throws StackEmptyException{
Stack<String> s = new Stack<String>();
String expression = jtfInfix.getText();
String delims = "+-*/()123456789 ";
StringTokenizer strToken = new StringTokenizer(expression, delims, true);
String result = "";
while(strToken.hasMoreTokens()){
String token = strToken.nextToken();
if(token.equals("(")){
s.push(token);
}
else if(token.equals(")")){
while(s.peek().equals("(") != true){
result += " " + s.pop();
}
}//first elseif
else if (checkOp(token)){
if(s.isEmpty() == true) {
s.push(token);
}
else {
if(getOrder(token) < findOrder(s.peek())) {
result += " " + s.pop();
s.push(token);
}
else {
s.push(token);
}
}
}
else {
result += " " + token;
}
}
while(s.isEmpty()) {
result += s.pop();
}
return result;
}// infixToPostFix()
public int findOrder(String token) {
int order = 0;
if((token.equals("+")) || (token.equals("-"))) {
order = 1;
}
else if((token.equals("*")) || (token.equals("%"))) {
order = 2;
}
else if(token.equals(")")) {
order = 0;
}
return order;
}
public int getOrder(String token) {
int order = 0;
if((token.equals("+")) || (token.equals("-")) ) {
order = 1;
}
else if((token.equals("*")) || (token.equals("%")) ) {
order = 2;
}
return order;
}
private boolean checkOp(String token) {
return ((token.equals("+")) || (token.equals("-")) || (token.equals("*")) ||
(token.equals("%")) );
}
There are a couple of errors
First you need to pop the parenthesis once it has been matched
while(s.peek().equals("(") != true){
result += " " + s.pop();
}
s.pop(); // pop the matching left parenthesis
and you want to pop everything off the stack once you have finished
while(s.isEmpty()) {
result += s.pop();
}
should be
while(!s.isEmpty()) {
result += " " + s.pop();
}
as a comment logging is helpful to see what is happebing.

Categories