Java - Irregular spaces in postfix expression - java

My program works fine, but I'm getting some irregular spaces in the output. For example, if the input is 44 * 5 + 6 the output is 44<2 spaces>5<1 space>*<1space>6<no space>+. I tried fiddling with all the lines of code that are adding to the String postfix, but to no avail. I'd like the output to be of the form: operand<1 space>operand<1 space>operator (i.e. 1 space between operands and operators."
Here's my code:
import java.util.*;
public class PostfixConversion {
public static void main(String args[]) {
System.out.print("Enter an expression: ");
String infix = new Scanner(System.in).nextLine();
String postfix = convertToPostfix(infix);
System.out.println(postfix);
//System.out.println("The result of calculation is: " + postfixEvaluate("23+"));
}
//converts infix expression into postfix expression
public static String convertToPostfix(String infixExp) {
String postFix = "The Postfix Expression is: ";
Stack<Character> stack = new Stack<Character>();
char character = ' ';
for(int i = 0; i < infixExp.length(); i++)
{
character = infixExp.charAt(i);
//determine if character is an operator
if(character == '*' || character == '-' || character == '/' || character == '+')
{
//postFix += " ";
while(!stack.empty() && precedence(stack.peek(), character))
postFix += stack.pop();
stack.push(character);
} else if(character == '(') {
stack.push(character);
} else if(character == ')') {
while(!stack.peek().equals('(') && !stack.isEmpty())
postFix += stack.pop();
if(!stack.isEmpty() && stack.peek().equals('('))
stack.pop(); // pop/remove left parenthesis
} else
postFix += character;
}
while(!stack.empty()) //add the remaining elements of stack to postfix expression
{
if(stack.peek().equals('('))
{
postFix = "There is no matching right parenthesis.";
return postFix;
}
postFix += stack.pop();
}
return postFix;
}
public static boolean precedence(char first, char second) {
int v1 = 0, v2 = 0;
//find value for first operator
if(first == '-' || first == '+')
v1 = 1;
else if(first == '*' || first == '/')
v1 = 2;
//find value for second operator
if(second == '-' || second == '+')
v2 = 1;
else if(second == '*' || second == '/')
v2 = 2;
if(v1 < v2)
return false;
return true;
}

First remove all whitespaces from input, so that they don't destroy your formatting:infixExp = infixExp.replaceAll("\\s",""); and then add whitespaces where needed.

Related

Infix to Postfix ' StringIndexOutOfBoundsException' error [duplicate]

This question already has an answer here:
What is a StringIndexOutOfBoundsException? How can I fix it?
(1 answer)
Closed 3 years ago.
I am setting up a method that turn a infix string into a postfix equation with a custom LinkStack.
I have tried to to check if the charAt(i) was null and a if statement to check if i is greater than exp.length() but neither worked.
public static String infixToPostfix(String exp)
{
// make variable
String result = new String("");
int temp = 0;
LinkedStack stack = new LinkedStack();
for (int i = 0; i<exp.length(); ++i)
{
char c = exp.charAt(i);
if(Character.isDigit(c))
{
int n = 0;
//extract the characters and store it in num
while(Character.isDigit(c))
{
n = n*10 + (int)(c-'0');
i++;
c = exp.charAt(i); //exception occurs
System.out.println(n);
}
i--;
//push the number in stack
stack.push(n);
//System.out.println(stack.size() + ", Stack size");
}
// If ( push it to the stack.
if (c == '(')
stack.push(c);
// If ) pop and output from the stack
// until an '(' is encountered.
else if (c == ')')
{
while (!stack.isEmpty() && stack.peek() != '(')
result += stack.pop();
if (!stack.isEmpty() && stack.peek() != '(')
return "Invalid Expression"; // invalid expression
else
stack.pop();
}
else // an operator is encountered
{
while (!stack.isEmpty() && pre(c) <= pre((char) stack.peek()))
result += stack.pop();
stack.push(c);
}
}
// pop all the operators from the stack
while (!stack.isEmpty())
result += stack.pop();
String temp2 = stack.print();
System.out.println(temp2);
return result;
}
I expect the output to be 469 645 + if the input is 496+645 but the actual output is java.lang.StringIndexOutOfBoundsException: String index out of range: 7.
while(Character.isDigit(c))
{
n = n*10 + (int)(c-'0');
i++;
c = exp.charAt(i); //exception occurs
System.out.println(n);
}
You aren't length checking here, so you readily parse right off the end of the string.
while(i < exp.length() && Character.isDigit(c))
{
n = n*10 + (int)(c-'0');
if (++i < exp.length()) {
c = exp.charAt(i); //exception occurs
}
System.out.println(n);
}
Note: I'd cache the length because of how many times you use it, but that's not the cause of your problem.
Note, however, that this is cleaner code style:
public class Foo {
public static void main(String[] args) {
String myString = "12345";
int index = 0;
for (char c: myString.toCharArray()) {
System.out.printf("Char at %d == %c\n", index, c);
++index;
}
}
}
Notice the for-loop. I didn't do your calculations or break out or anything, but this is a cleaner way.
You can also do...
for (int index = 0; index < exp.length(); ++index) {
char c = exp.charAt(index);
if (!Character.isDigit(c)) {
break;
}
// Do other stuff here.
}
There are a variety of other ways to structure your code. Your while loop is awkward.

Pushing certain chars to certain strings. Infix to postfix

I want to make a calculator that converts infix to postfix, using only strings and characters.
here's the requirements:
for i=1 to m:
if c_i is an operand: Transfer c_i to output.
-if c_i is a left parentheses: Push c_i to tmp.
-if c_i is a right parentheses: Pop elements from tmp and transfer
-them to output until a left-parentheses
-is met. Pop left-parentheses.
if c_i is an operator: Let the top tmp element be t. Pop and
-transfer elements from tmp to output
-until:
-p(t) < p(c_i) or
-t is a left-parentheses or
-tmp is empty.
-Push c_i to tmp.
static String infixToPostfix(String infix){
String postfix = "";
infix = readLine();
String temp ="";
String output ="";
for (int i=0 ; i<infix.length(); i++) {
if (infix.charAt(i) == '+') {
infix = postfix;
}
else if (infix.charAt(i) == '-') {
infix = postfix;
}
else if (infix.charAt(i) == '*') {
infix = postfix;
}
else if (infix.charAt(i) == '/') {
infix = postfix;
}
else if (infix.charAt(i) == '(') {
infix = temp ;
}
else if (infix.charAt(i) == ')') {
temp=postfix;
}
}
return postfix;
}
Your code seems to be incomplete. Here is my own method to convert an Infix String to Postfix. Hope it helps.
boolean chk = true;
for(int i=0; i<expression.length(); i++) {
char ch = expression.charAt(i);
//Conditions for generating postfix String
if(ch=='(') {
operator.push(ch);
chk=false;
}
else if(isDigit(ch)) {
if(!chk) {
postfix = postfix + " " + ch;
}
else {
postfix = postfix + ch;
}
chk=true;
}
else if(ch == '+' || ch=='-') {
if(operator.isEmpty()) {
operator.push(ch);
}
else if(operator.peep()=='/'|| perator.peep()=='*'||operator.peep()=='-') {
postfix = postfix + " " + operator.pop();
operator.push(ch);
}
else {
operator.push(ch);
}
chk = false;
}
else if(ch == '*' || ch == '/') {
if(operator.isEmpty()) {
operator.push(ch);
}
else if(operator.peep()=='+' || operator.peep()=='-') {
operator.push(ch);
}
else {
postfix = postfix + " " + operator.pop();
operator.push(ch);
}
chk = false;
}
else if(ch == ')') {
while(operator.peep()!='(') {
postfix = postfix + " " + operator.pop();
}
operator.pop();
}
}
while(!operator.isEmpty()) {
postfix = postfix + " " + operator.pop();
}

Converting infix to prefix using a Stack (LinkedList)

I am trying to write a method that converts infix to prefix and to do that i want to read a sting reverse and use a stack. When i execute this code i am getting an exception at character = expression.charAt(limit); how can i fix that code?
My input was 1+3 and the error i got was:
Exception in thread "main" java.lang.StringIndexOutOfBoundsException:
String index out of range: 3 at java.lang.String.charAt(Unknown
Source) at PrefixTranslator.translate(PrefixTranslator.java:27) at
PrefixTranslatorTest.main(PrefixTranslatorTest.java:11)
PrefixTranslator Class:
public class PrefixTranslator
{
static private String expression;
private MyStack<Character> stack = new MyStack<Character>();
//Constructor
public PrefixTranslator(String infixExpression)
{
expression = infixExpression;
}//End of constructor
public String translate()
{
//Declare Method Variables
String input = "";
String output = "";
char character = ' ';
char nextCharacter = ' ';
for(int limit = expression.length(); limit > 0 ; limit--)
{
character = expression.charAt(limit);
if(isOperator(character))
{
output = output + character + " ";
}
else if(character == '(')
{
stack.push(character);
}
else if(character == ')')
{
while(!stack.top().equals('('))
output = output + stack.pop() + " ";
stack.pop();
}
else
{
if(Character.isDigit(character) && (limit + 1) < limit && Character.isDigit(expression.charAt(limit+1)))
{
stack.push(character);
stack.push(expression.charAt(limit+1));
}
else if(Character.isDigit(character))
{
stack.push(character);
}
else
{
output = output + character;
}
}
}//End of for
while(!stack.isEmpty())
{
output = output + stack.pop() + " ";
}
return output;
}//End of translate method
//Check priority on characters
public static int precedence(char operator)
{
if(operator == '+' || operator =='-')
return 1;
else if(operator == '*' || operator == '/')
return 2;
else
return 0;
}//End of priority method
public boolean isOperator(char element)
{
if(element == '*' || element == '-' || element == '/' || element == '+')
return true;
else
return false;
}//End of isOperator method
}//End of class
PrefixTranslatorTest Class:
import java.util.Scanner;
public class PrefixTranslatorTest{
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter the expression that you want to convert to prefix.");
String expression = input.next();
PrefixTranslator translator = new PrefixTranslator(expression);
System.out.println(translator.translate());
}
}
For the given input 1+3 expression.length() returns 3 and you can refer to indexes 0-2 of that string. So, your loop shouldn't be:
for(int limit = expression.length(); limit > 0 ; limit--)
And it should be
for(int limit = expression.length() - 1; limit >= 0 ; limit--)
The first index of Java arrays is 0 and the method length() returns the number of elements of array. If you need the last element's index, use
length() - 1.
So instead of
for (int limit = expression.length(); limit > 0; limit--)
use
for (int limit = expression.length() - 1; limit >= 0; limit--)

Reading in text file gives ArrayIndexOutOfBoundsException

I am attempting to read this .txt file into my program (as an improvement over manual input) and i am having trouble converting my methods to accept the input txt file. i get a arrayindexoutofboundsexception on line "infix[--pos]='\0';"
class Functions {
void postfix(char infix[], char post[]) {
int position, und = 1;
int outposition = 0;
char topsymb = '+';
char symb;
Stack opstk = new Stack();
opstk.top = -1;
for (position = 0; (symb = infix[position]) != '\0'; position++) {
if (isoperand(symb))
post[outposition++] = symb;
else {
if (opstk.isempty() == 1)
und = 1;
else {
und = 0;
topsymb = opstk.pop();
}
while (und == 0 && precedence(topsymb, symb) == 1) {
post[outposition++] = topsymb;
if (opstk.isempty() == 1)
und = 1;
else {
und = 0;
topsymb = opstk.pop();
}
}// end while
if (und == 0)
opstk.push(topsymb);
if (und == 1 || (symb != ')'))
opstk.push(symb);
else
topsymb = opstk.pop();
}// end else
}// end for
while (opstk.isempty() == 0)
post[outposition++] = opstk.pop();
post[outposition] = '\0';
}// end postfix function
int precedence(char topsymb, char symb) {
/* check precedence and return 0 or 1 */
if (topsymb == '(')
return 0;
if (symb == '(')
return 0;
if (symb == ')')
return 1;
if (topsymb == '$' && symb == '$')
return 0;
if (topsymb == '$' && symb != '$')
return 1;
if (topsymb != '$' && symb == '$')
return 0;
if ((topsymb == '*' || topsymb == '/') && (symb != '$'))
return 1;
if ((topsymb == '+' || topsymb == '-') && (symb == '-' || symb == '+'))
return 1;
if ((topsymb == '+' || topsymb == '-') && (symb == '*' || symb == '/'))
return 0;
return 1;
} /* end precedence function */
private boolean isoperand(char symb) {
/* Return 1 if symbol is digit and 0 otherwise */
if (symb >= '0' && symb <= '9')
return true;
else
return false;
}/* end isoperand function */
}
public class Driver {
public static void main(String[] args) throws IOException {
Functions f = new Functions();
char infix[] = new char[80];
char post[] = new char[80];
int pos = 0;
char c;
System.out.println("\nEnter an expression is infix form : ");
try {
BufferedReader in = new BufferedReader(new FileReader("infix.txt"));
String str;
while ((str = in.readLine()) != null) {
infix = str.toCharArray();
}
in.close();
} catch (IOException e) {
}
infix[--pos] = '\0';
System.out.println("The original infix expression is : ");
for (int i = 0; i < pos; i++)
System.out.print(infix[i]);
f.postfix(infix, post);
System.out.println("\nThe postfix expression is : ");
for (int i = 0; post[i] != '\0'; i++)
System.out.println(post[i]);
}
}
Do should never ever do like this:
try {
...
} catch (IOException e) {
}
You loose some essential information about your code-running.
At lease you should print the stack trace to follow the investigation:
e.printStackTrace();
You may have a FileNotFound exception.
In addition you try to index your array to -1 in infix[--pos], pos is set to 0 before this statement.
1) Totally aside, but I think line in main should read:System.out.println("\nEnter an expression in infix form : ");
2) As well, i agree about the catch statement. You already have narrowed it down to being an IOExcpetion, but you can find so much more info out by printing wither of the following inside the catch
System.err.println(e.getMessage()); or e.printStackTrace()
Now to answer your question. You are initializing pos to the value 0, but the you are doing a PREINCREMENT on the line infix[--pos] = '\0'; so pos becomes -1 (clearly outside the scope of the array bounddaries).
I think you want to change that to a post increment infix[pos--] = '\0';. Perhaps?
And yes, your code DOES Look like C...

infix to postfix program not working [duplicate]

This question already has answers here:
Handling parenthesis while converting infix expressions to postfix expressions
(2 answers)
Closed 6 years ago.
I am supposed to write a program to convert infix to postfix. It works for some, but other times not correctly. Especially on infix expressions containing parantheses. Could anyone give me a clue why this is wrong? For example, the infix expression
( ( 5 + 5 * ( 6 - 2 ) + 4 ^ 2 ) * 8 )
returns 5562-*42^++8*((2.
import java.io.*;
import java.util.Scanner;
public class InfixToPostfix
{
//class attributes
private char curValue;
private String postfix;
private LineWriter lw;
private ObjectStack os;
//constructor
public InfixToPostfix(LineWriter l, ObjectStack o)
{
curValue = ' ';
lw=l;
os=o;
}
public String conversion(String buf)
{
String temp =" ";
StringBuffer postfixStrBuf= new StringBuffer(temp);
char popped= new Character(' ');
char topped=' ';
for (int i=0; i<buf.length(); i++)
{
curValue= buf.charAt(i);
if (curValue == '(')
os.push(curValue);
if (curValue == ')')
{
while (popped != '(')
{
popped = ((Character)os.pop());
if (popped != '(')
postfixStrBuf.append(popped);
}
}
if (isOperator(curValue))
{
if( os.isEmpty())
os.push((Character)(curValue));
else
topped=((Character)os.top());
if ( (priority(topped)) >= (priority(curValue)) && (topped != ' ') )
{
popped = ((Character)os.pop());
if (popped != '(')
postfixStrBuf.append(popped);
//if it is a left paranthess, we want to go ahead and push it anyways
os.push((Character)(curValue));
}
if ( (priority(topped)) < (priority(curValue)) && (topped != ' ') )
os.push((Character)(curValue));
}
else if (!isOperator(curValue) && (curValue != ' ') && (curValue != '(' ) && (curValue != ')' ))
postfixStrBuf.append(curValue);
}
//before you grab the next line of the file , pop off whatever is remaining off the stack and append it to
//the infix expression
getRemainingOp(postfixStrBuf);
return postfix;
//postfixStrBuf.delete(0, postfixStrBuf.length());
}
public int priority(char curValue)
{
switch (curValue)
{
case '^': return 3;
case '*':
case '/': return 2;
case '+':
case '-': return 1;
default : return 0;
}
}
public boolean isOperator(char curValue)
{
boolean operator = false;
if ( (curValue == '^' ) || (curValue == '*') || (curValue == '/') || (curValue == '+' ) || (curValue == '-') )
operator = true;
return operator;
}
public String getRemainingOp(StringBuffer postfixStrBuf)
{
char popped=' ';
while ( !(os.isEmpty()) )
{
opped = ((Character)os.pop());
postfixStrBuf.append(popped);
}
postfix=postfixStrBuf.toString();
return postfix;
}
}
I will only post how the inner loop should look like (without the castings everywhere):
if (curValue == '(') {
os.push(curValue);
} else if (curValue == ')') {
if(!os.isEmpty()) {
topped = os.pop();
while (!os.isEmpty() && (topped != '(')) {
postfixStrBuf.append(topped);
topped = os.pop();
}
}
} else if (isOperator(curValue)) {
if (os.isEmpty()) {
os.push(curValue);
} else {
while(!os.isEmpty() && (priority(os.top()) >= priority(curValue))) {
popped = os.pop();
postfixStrBuf.append(popped);
}
os.push(curValue);
}
} else if (curValue != ' ') {
postfixStrBuf.append(curValue);
}
Disclosure: it is pretty late already so I hope it is fine. You should fix the way variables are initialized and return of the getRemainingOp method.

Categories

Resources