Unknown error in converting a multiple digit infix expression to postfix - java

The function code for converting infix to postfix expression, as follows
package swapnil.calcii;
import android.util.Log;
import java.util.Stack;
public class Calculate {
private static final String operators = "-+/*";
private static final String operands = "0123456789";
public int evalInfix(String infix) {
return evaluatePostfix(convert2Postfix(infix));
}
public String convert2Postfix(String infixExpr) {
char[] chars = infixExpr.toCharArray();
Stack<String> stack = new Stack<String>();
StringBuilder out = new StringBuilder(infixExpr.length());
for (char c : chars) {
if (isOperator(c)) {
while (!stack.isEmpty() && !stack.peek().equals("(")) {
if (operatorGreaterOrEqual(stack.peek(), c)) {
out.append(stack.pop());
} else {
break;
}
}
String s = ""+c;
stack.push(s);
}
else if (c == '(') {
String s = ""+c;
stack.push(s);
} else if (c == ')') {
while (!stack.isEmpty() && !stack.peek().equals("(")) {
out.append(stack.pop());
}
if (!stack.isEmpty()) {
stack.pop();
}
} else if (isOperand(c)) {
try{
StringBuilder num = new StringBuilder();
while(isOperand(stack.peek().charAt(0))) {
num.append(stack.pop());
out.append(num);
}
} catch (Exception e) {
Log.d("errrr", "error in inserting " + e.getMessage());
out.append(c);
}
out.append(c);
}
}
while (!stack.empty()) {
out.append(stack.pop());
}
return out.toString();
}
public int evaluatePostfix(String postfixExpr) {
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars) {
if (isOperand(c)) {
stack.push(c - '0'); // convert char to int val
} else if (isOperator(c)) {
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c) {
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private int getPrecedence(char operator) {
int ret = 0;
if (operator == '-' || operator == '+') {
ret = 1;
} else if (operator == '*' || operator == '/') {
ret = 2;
}
return ret;
}
private boolean operatorGreaterOrEqual(String op1, char op2) {
char op = op1.charAt(0);
return getPrecedence(op) >= getPrecedence(op2);
}
private boolean isOperator(char val) {
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val) {
return operands.indexOf(val) >= 0;
}
}
crashes with unknown error.
I've written it myself and I can't figure out where I am going wrong.
Function works fine, if pushing one char when checking isOperand(c)
But using StringBuilder to push a multiple digit number crashes the code.
Help

Related

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.

My Infix to postfix Code does not work [duplicate]

This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
I tried making my infix to postfix code, it works without the braces, but when I try to include the portion to account for braces, it crashes, here is the main part of the code:
for (i=0; i<characters.length; i++)
{
if (characters[i]=='*' || characters[i]=='/' || characters[i]=='+' || characters[i]=='-' || characters[i]=='(' || characters[i]==')'){
if (postfix.empty() && characters[i]!=')')
postfix.push(characters[i]);
else if (!postfix.empty()){
if (characters[i]=='(')
postfix.push(characters[i]);
if (characters[i]=='*' || characters[i]=='/')
priority2=1;
if (characters[i]=='+' || characters[i]=='-')
priority2=0;
if (characters[i]==')'){
while (postfix.peek()!='(') //loop until we see the closing bracket
System.out.print(postfix.pop()); //pop everything till we see the closing bracket
postfix.pop(); //to pop the bracket
}
if (!postfix.empty())
peeked=postfix.peek();
if (peeked=='*' || peeked=='/')
priority=1;
if (peeked=='+' || peeked=='-')
priority=0;
if (priority2>priority)
postfix.push(characters[i]);
else{
while (!postfix.empty())
System.out.print(postfix.pop());
postfix.push(characters[i]);
}
}
}
else
System.out.print(characters[i]);
}
while (!postfix.empty())
System.out.print(postfix.pop());
Any help would be appreciated. It breaks when it comes to a brace.
You can get some insight from my implementation of Infix To Postfix program, which is based on the standard algorithm for doing such conversions. Here it is:
import java.util.Scanner;
import java.util.Stack;
public class InfixPostfix
{
private Stack<Character> stack;
private StringBuilder postfixExpression;
public InfixPostfix()
{
stack = new Stack<>();
postfixExpression = new StringBuilder();
String infix = getInfixExpression();
if (isValidInfix(infix))
{
System.out.println(convertToPostfix(infix));
}
else
{
System.out.println("Invalid Expression");
}
}
private boolean isValidInfix(String infix)
{
int parenthesisCounter = 0;
for (int i = 0; i < infix.length(); i++)
{
char ch = infix.charAt(i);
if (ch == '(')
parenthesisCounter++;
else if (ch == ')')
parenthesisCounter--;
if (parenthesisCounter < 0)
return false;
}
if (parenthesisCounter == 0)
return true;
return false;
}
private String convertToPostfix(String infix)
{
for (int i = 0; i < infix.length(); i++)
{
char ch = infix.charAt(i);
switch (ch)
{
case '+':
case '-':
processOperatorOfPrecedence(ch, 1);
break;
case '*':
case '/':
processOperatorOfPrecedence(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
processParenthesis(ch);
break;
default:
postfixExpression.append(ch);
break;
}
}
while (!stack.isEmpty())
{
postfixExpression.append(stack.pop());
}
return postfixExpression.toString();
}
private void processOperatorOfPrecedence(char operator, int precedence)
{
while (!stack.isEmpty())
{
char topOperator = stack.pop();
if (topOperator == '(')
{
stack.push(topOperator);
break;
}
else
{
int operatorPrecedence;
if (topOperator == '+' || topOperator == '-')
operatorPrecedence = 1;
else
operatorPrecedence = 2;
if (operatorPrecedence < precedence)
{
stack.push(topOperator);
break;
}
else
postfixExpression.append(topOperator);
}
}
stack.push(operator);
}
private void processParenthesis(char ch)
{
while (!stack.isEmpty())
{
char character = stack.pop();
if (character == '(')
break;
else
postfixExpression.append(character);
}
}
private String getInfixExpression()
{
Scanner scanner = new Scanner(System.in);
System.out.println("Enter an infix math expression: ");
String input = scanner.nextLine();
scanner.close();
return input;
}
public static void main(String[] args)
{
new InfixPostfix();
}
}

Java print certain characters from an array

I have a string array that looks like this:
[67, +, 12, -, 45]
I want to print it out so that it looks like this:
67 12 + 45 -
Here's the code I'm trying to use to do this.
String[] temp = line.split(" ");
String tmp = line.replaceAll("\\s+","");
for(int i = 0; i < temp.length; i++)
{
if(isInt(temp[i]) == false)
{
expression = temp[i];
firstExp = true;
}
else if(isInt(temp[i]) == false && firstExp == true && secondExp == false)
{
System.out.print(expression);
secondExp = true;
}
else if(isInt(temp[i]) == false && firstExp == true && secondExp == true)
{
System.out.print(expression);
firstExp = false;
secondExp = false;
}
else
{
System.out.print(temp[i]);
}
}
firstExp and secondExp are Booleans that check for the expressions that should appear in the array. isInt() is just a method used to determine if the string is a number. Right now, all this code does is output this:
671245
public static void main (String[] args) throws java.lang.Exception
{
String[] expr = new String[]{"67", "+", "45", "-", "12", "*", "5", "/", "78"};
int current = 0;
StringBuilder postfix = new StringBuilder();
// handle first three
postfix.append(expr[current]).append(" ");
postfix.append(expr[current+2]).append(" ");
postfix.append(expr[current+1]).append(" ");
current += 3;
// handle rest
while( current <= expr.length-2 ){
postfix.append(expr[current+1]).append(" ");
postfix.append(expr[current]).append(" ");
current += 2;
}
System.out.println(postfix.toString());
}
Outputs:
67 45 + 12 - 5 * 78 /
You can run/edit this at: http://ideone.com/zcdlEq
I guess what you are trying to do is converting infix expression to post fix. Some time back I had written the following code:
public class InfixToPostfix {
private Stack stack;
private String input;
private String output = "";
public InfixToPostfix(String in) {
input = in;
int stackSize = input.length();
stack = new Stack(stackSize);
}
public String translate() {
for (int j = 0; j < input.length(); j++) {
char ch = input.charAt(j);
switch (ch) {
case '+':
case '-':
hastOperator(ch, 1);
break;
case '*':
case '/':
hastOperator(ch, 2);
break;
case '(':
stack.push(ch);
break;
case ')':
hasSuperior(ch);
break;
default:
output = output + ch;
break;
}
}
while (!stack.isEmpty()) {
output = output + stack.pop();
}
System.out.println(output);
return output;
}
public void hastOperator(char op, int precedence) {
while (!stack.isEmpty()) {
char opTop = stack.pop();
if (opTop == '(') {
stack.push(opTop);
break;
}
else {
int prec2;
if (opTop == '+' || opTop == '-')
prec2 = 1;
else
prec2 = 2;
if (prec2 < precedence) {
stack.push(opTop);
break;
}
else
output = output + opTop;
}
}
stack.push(op);
}
public void hasSuperior(char ch){
while (!stack.isEmpty()) {
char chx = stack.pop();
if (chx == '(')
break;
else
output = output + chx;
}
}
public static void main(String[] args)
throws IOException {
String input = "67 + 12 - 45";
String output;
InfixToPostfix theTrans = new InfixToPostfix(input);
output = theTrans.translate();
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);
}
}
}
You may need to modify this program to read from an array, but that is very trivial.
Here's how you do it in one line:
System.out.println(Arrays.toString(temp).replaceAll("[^\\d +*/-]", "").replaceAll("[+*/-]) (\\d+)", "$2 $1"));

Recognizing negative values when converting infix to postfix

This is my class:
import java.io.*;
import java.util.*;
import java.lang.*;
import java.util.Scanner;
import java.util.List;
import java.util.Stack;
/**
*
* #author rtibbetts268
*/
public class InfixToPostfix
{
/**
* Operators in reverse order of precedence.
*/
private static final String operators = "_-+/*";
private static final String operands = "0123456789x";
public String xToValue(String postfixExpr, String x)
{
char[] chars = postfixExpr.toCharArray();
StringBuilder newPostfixExpr = new StringBuilder();
for (char c : chars)
{
if (c == 'x')
{
newPostfixExpr.append(x);
}
else
{
newPostfixExpr.append(c);
}
}
return newPostfixExpr.toString();
}
public String convert2Postfix(String infixExpr)
{
char[] chars = infixExpr.toCharArray();
StringBuilder in = new StringBuilder(infixExpr.length());
for (int i : chars)
{
if (infixExpr.charAt(i) == '-')
{
if (isOperand(infixExpr.charAt(i+1)))
{
if (i != infixExpr.length())
{
if (isOperator(infixExpr.charAt(i-1)))
in.append('_');
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
else
{
in.append(infixExpr.charAt(i));
}
}
chars = in.toString().toCharArray();
Stack<Character> stack = new Stack<Character>();
StringBuilder out = new StringBuilder(in.toString().length());
for (char c : chars)
{
if (isOperator(c))
{
while (!stack.isEmpty() && stack.peek() != '(')
{
if (operatorGreaterOrEqual(stack.peek(), c))
{
out.append(stack.pop());
}
else
{
break;
}
}
stack.push(c);
}
else if (c == '(')
{
stack.push(c);
}
else if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
{
out.append(stack.pop());
}
if (!stack.isEmpty())
{
stack.pop();
}
}
else if (isOperand(c))
{
out.append(c);
}
}
while (!stack.empty())
{
out.append(stack.pop());
}
return out.toString();
}
public int evaluatePostfix(String postfixExpr)
{
char[] chars = postfixExpr.toCharArray();
Stack<Integer> stack = new Stack<Integer>();
for (char c : chars)
{
if (isOperand(c))
{
stack.push(c - '0'); // convert char to int val
}
else if (isOperator(c))
{
int op1 = stack.pop();
int op2 = stack.pop();
int result;
switch (c) {
case '*':
result = op1 * op2;
stack.push(result);
break;
case '/':
result = op2 / op1;
stack.push(result);
break;
case '+':
result = op1 + op2;
stack.push(result);
break;
case '-':
result = op2 - op1;
stack.push(result);
break;
}
}
}
return stack.pop();
}
private int getPrecedence(char operator)
{
int ret = 0;
if (operator == '_')
{
ret = 0;
}
if (operator == '-' || operator == '+')
{
ret = 1;
}
else if (operator == '*' || operator == '/')
{
ret = 2;
}
return ret;
}
private boolean operatorGreaterOrEqual(char op1, char op2)
{
return getPrecedence(op1) >= getPrecedence(op2);
}
private boolean isOperator(char val)
{
return operators.indexOf(val) >= 0;
}
private boolean isOperand(char val)
{
return operands.indexOf(val) >= 0;
}
}
In it I change infix expressions to postfix expressions with the method convert2Postfix()
There is a small section in it at the very beginning where I am rewriting the string input with all negative numbers having a '_' infront of them instead of a "-". It doesn't work.
ex: change -4 to _4
What do I need to do to make this work?
You have a number of errors here, here is the first one:
for (int i : chars)
chars is converted to the corresponding int. For example if chars contains one single character 'A':
char [] chars = new char[1];
chars[0] = 'A';
for(int i: chars){
System.out.println(i); //You will have a '65' here
}
What you really mean is probably:
for (int i=0;i<chars.length;++i)
This is also wrong:
if (isOperator(infixExpr.charAt(i-1)))
It should be :
if (isOperator(infixExpr.charAt(i)))
Then there is a problem in the way you put and remove elements in the stack.
After all this changes you should also do this:
return out.reverse().toString();
instead of :
return out.toString();
Here is what I ended up with: http://pastebin.com/2TLqPUsH
(Change the name of the classes of course)

Postfix stack calculator

I've created a stack calculator for my Java class to solve equations such as
2 + ( 2 * ( 10 – 4 ) / ( ( 4 * 2 / ( 3 + 4) ) + 2 ) – 9 )
2 + { 2 * ( 10 – 4 ) / [ { 4 * 2 / ( 3 + 4) } + 2 ] – 9 }
We are suppose to implement { } [ ] into our code. I did it with just parentheses. It works 100% with just ( ). When I try to add { } [ ], it goes bananas.
This is what I have so far:
package stackscalc;
import java.util.Scanner;
import java.util.Stack;
import java.util.EmptyStackException;
class Arithmetic {
int length;
Stack stk;
String exp, postfix;
Arithmetic(String s) {
stk = new Stack();
exp = s;
postfix = "";
length = exp.length();
}
boolean isBalance() {
boolean fail = false;
int index = 0;
try {
while (index < length) {
char ch = exp.charAt(index);
switch(ch) {
case ')':
stk.pop();
break;
case '(':
stk.push(new Character(ch));
break;
default:
break;
}
index++;
}
} catch (EmptyStackException e) {
fail = true;
}
return stk.empty() && !fail;
}
void postfixExpression() {
String token = "";
Scanner scan = new Scanner(exp);
stk.clear();
while(scan.hasNext()) {
token = scan.next();
char current = token.charAt(0);
if (isNumber(token)) {
postfix = postfix + token + " ";
} else if(isParentheses(current)) {
if (current == '(') {
stk.push(current);
} else {
Character ch = (Character) stk.peek();
char nextToken = ch.charValue();
while(nextToken != '(') {
postfix = postfix + stk.pop() + " ";
ch = (Character) stk.peek();
nextToken = ch.charValue();
}
stk.pop();
}
} else {
if (stk.empty()) {
stk.push(current);
} else {
Character ch = (Character) stk.peek();
char top = ch.charValue();
if (hasHigherPrecedence(top, current)) {
stk.push(current);
} else {
ch = (Character) stk.pop();
top = ch.charValue();
stk.push(current);
stk.push(top);
}
}
}
}
try {
Character ch = (Character) stk.peek();
char nextToken = ch.charValue();
while (isOperator(nextToken)) {
postfix = postfix + stk.pop() + " ";
ch = (Character) stk.peek();
nextToken = ch.charValue();
}
} catch (EmptyStackException e) {}
}
boolean isNumber(String s) {
try {
int Num = Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
}
return true;
}
void evaluateRPN() {
Scanner scan = new Scanner(postfix);
String token = "";
stk.clear();
while(scan.hasNext()) {
try {
token = scan.next();
if (isNumber(token)) {
stk.push(token);
} else {
char current = token.charAt(0);
double t1 = Double.parseDouble(stk.pop().toString());
double t2 = Double.parseDouble(stk.pop().toString());
double t3 = 0;
switch (current) {
case '+': {
t3 = t2 + t1;
stk.push(t3);
break;
}
case '-': {
t3 = t2 - t1;
stk.push(t3);
break;
}
case '*': {
t3 = t2 * t1;
stk.push(t3);
break;
}
case '/': {
t3 = t2 / t1;
stk.push(t3);
break;
}
default: {
System.out.println("Reverse Polish Notation was unable to be preformed.");
}
}
}
} catch (EmptyStackException e) {}
}
}
String getResult() {
return stk.toString();
}
int stackSize() {
return stk.size();
}
boolean isParentheses(char current) {
if ((current == '(') || (current == ')')) {
return true;
} else {
return false;
}
}
boolean isOperator(char ch) {
if ((ch == '-')) {
return true;
} else if ((ch == '+')) {
return true;
}
else if ((ch == '*')) {
return true;
}
else if((ch == '/')) {
return true;
} else {
}
return false;
}
boolean hasHigherPrecedence(char top, char current) {
boolean HigherPre = false;
switch (current) {
case '*':
HigherPre = true;
break;
case '/':
HigherPre = true;
break;
case '+':
if ((top == '*') || (top == '/') || (top == '-')) {
HigherPre = false;
} else {
HigherPre = true;
}
break;
case '-':
if ((top == '*') || (top == '/') || (top == '-')) {
HigherPre = false;
} else {
HigherPre = true;
}
break;
default:
System.out.println("Higher Precedence Unsuccessful was unable to be preformed.");
break;
}
return HigherPre;
}
String getPostfix() {
return postfix;
}
}
What I am assuming is that (), {}, and [] all have the same weight in terms of order of operations, and you just need to modify your code in order to allow for all three interchangeably.
If that is the case, I would just use the matcher class with a simple regex check to see if the current char that you are looking at is either a parenthesis, curly brace, or bracket.
//convert char to string
String temp += currentChar;
//this will check for (, [, and { (need escapes because of how regex works in java)
Pattern bracePattern = Pattern.compile("[\(\{\[]");
Matcher matcher = numPatt.matcher(temp);
if(matcher.find()){
//you know you have a grouping character
}
This code should allow you to find all the opening grouping characters (just substitute (,{, and [ for ),} and ] in the regex to find closing characters). This can be used in your isParenthesis() method.
You could use a method like this to streamline checking if a '(', '[', or '{' is matched or not.
static char getExpected(char val){
char expected=' ';
switch (val) {
case '(':
expected=')';
break;
case '[':
expected=']';
break;
case '{':
expected='}';
break;
}
return expected;
}

Categories