I have implemented the algorithm that I have found on this link to evaluate an arithmetic expression for j2me. But it works fine only when I have single digit operands i.e. 2, 5, 7, 3 but not for 456, 56, 34.45 etc. I did some changes as i knew i had to add the numbers found not one by one but till we end with a digit. Then I found this link also but still things didn't go well as expected. First I had tried the exp4j library but I guess that does not work on j2me. The code has become very messy right now. Could I get any opinions on how should I go about this problem? Any help on this would be appreciated.
Code that initially worked only for single digit operands:
import java.util.Stack;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SampleInfixToPostfixToResult {
static Stack stack=new Stack();
static StringBuffer p=new StringBuffer();
static Vector v=new Vector();
public static StringBuffer toPostfix(String q)
{
for(int i=0;i<q.length();i++)
{
if(q.charAt(i)=='0'||q.charAt(i)=='1'||q.charAt(i)=='2'||q.charAt(i)=='3'||q.charAt(i)=='4'||q.charAt(i)=='5'||q.charAt(i)=='6'||q.charAt(i)=='7'||q.charAt(i)=='8'||q.charAt(i)=='9')
{
p.append(q.charAt(i));
}
else if(q.charAt(i)=='(')
{
stack.push(q.charAt(i));
}
else if(q.charAt(i)==')')
{
for(int j=0;!stack.empty()&&!stack.peek().equals('(');j++)
{
p.append(stack.pop());
}
stack.pop();
}
else if(q.charAt(i)=='+'||q.charAt(i)=='-'||q.charAt(i)=='/'||q.charAt(i)=='*')
{
if(stack.empty()||stack.peek().equals('('))
stack.push(q.charAt(i));
else
{
while(!stack.empty()&&!stack.peek().equals('(')&&isHigh(q.charAt(i), stack.peek()))
{
p.append(stack.pop());
}
stack.push(q.charAt(i));
}
}
}
while(!stack.empty())
{
p.append(stack.pop());
}
System.out.println(p);
return p;
}
public static boolean isHigh(char op, Object AtStack)
{
char opAtStack=AtStack.toString().charAt(0);
boolean isHigh=false;
if((op==opAtStack))
isHigh=true;
if((op=='+'||op=='-')&&(opAtStack=='/'||opAtStack=='*'))
{
isHigh=true;
}
if((op=='+'&&opAtStack=='-')||(op=='-'&&opAtStack=='+')||(op=='/'&&opAtStack=='*')||(op=='*'&&opAtStack=='/'))
{
isHigh=true;
}
return isHigh;
}
public static double result(StringBuffer p)
{
for(int i=0;i<p.length();i++)
{
System.out.println(p.charAt(i));
if(p.charAt(i)=='0'||p.charAt(i)=='1'||p.charAt(i)=='2'||p.charAt(i)=='3'||p.charAt(i)=='4'||p.charAt(i)=='5'||p.charAt(i)=='6'||p.charAt(i)=='7'||p.charAt(i)=='8'||p.charAt(i)=='9')
{
stack.push(p.charAt(i));
}
if(p.charAt(i)=='+'||p.charAt(i)=='-'||p.charAt(i)=='/'||p.charAt(i)=='*')
{
double a=Double.parseDouble(stack.pop().toString());
double b=Double.parseDouble(stack.pop().toString());
if(p.charAt(i)=='+')
{
stack.push(b+a);
}
else if(p.charAt(i)=='-')
{
stack.push(b-a);
}
else if(p.charAt(i)=='/')
{
stack.push(b/a);
}
else if(p.charAt(i)=='*')
{
stack.push(b*a);
}
}
}
System.out.println(stack);
return 0;
}
public static void main(String[] args) {
// TODO code application logic here
String s=new String("65*(76+2)-0/4+(2*5-6*(2*5))");
SampleInfixToPostfixToResult.result(SampleInfixToPostfixToResult.toPostfix(s));
System.out.println(66*(76+2)-0/4+(2*5-6*(2*5)));
}
}
Updated code that I worked on for evaluation of multi-digit operand (really messed up)
import java.util.Stack;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
public class SampleInfixToPostfixToResult {
static Stack stack=new Stack();
static StringBuffer p=new StringBuffer();
static Vector v=new Vector();
public static Vector toPostfix(String q)
{
for(int i=0;i<q.length();i++)
{
if(q.charAt(i)=='0'||q.charAt(i)=='1'||q.charAt(i)=='2'||q.charAt(i)=='3'||q.charAt(i)=='4'||q.charAt(i)=='5'||q.charAt(i)=='6'||q.charAt(i)=='7'||q.charAt(i)=='8'||q.charAt(i)=='9')
{
StringBuffer tn=new StringBuffer();
while(i<q.length()&&(q.charAt(i)=='0'||q.charAt(i)=='1'||q.charAt(i)=='2'||q.charAt(i)=='3'||q.charAt(i)=='4'||q.charAt(i)=='5'||q.charAt(i)=='6'||q.charAt(i)=='7'||q.charAt(i)=='8'||q.charAt(i)=='9'))
{
tn.append(q.charAt(i++));
}
v.add(tn);
}
else if(q.charAt(i)=='(')
{
stack.push(q.charAt(i));
}
else if(q.charAt(i)==')')
{
for(int j=0;!stack.empty()&&!stack.peek().equals('(');j++)
{
v.add(stack.pop());
}
stack.pop();
}
else if(q.charAt(i)=='+'||q.charAt(i)=='-'||q.charAt(i)=='/'||q.charAt(i)=='*')
{
if(stack.empty()||stack.peek().equals('('))
stack.push(q.charAt(i));
else
{
while(!stack.empty()&&!stack.peek().equals('(')&&isHigh(q.charAt(i), stack.peek()))
{
v.add(stack.pop());
}
stack.push(q.charAt(i));
}
}
}
while(!stack.empty())
{
v.add(stack.pop());
}
return v;
}
public static boolean isHigh(char op, Object AtStack)
{
char opAtStack=AtStack.toString().charAt(0);
boolean isHigh=false;
if((op==opAtStack))
isHigh=true;
if((op=='+'||op=='-')&&(opAtStack=='/'||opAtStack=='*'))
{
isHigh=true;
}
if((op=='+'&&opAtStack=='-')||(op=='-'&&opAtStack=='+')||(op=='/'&&opAtStack=='*')||(op=='*'&&opAtStack=='/'))
{
isHigh=true;
}
return isHigh;
}
public static double result(Vector p)
{
for(int i=0;i<p.size();i++)
{
System.out.println(p.get(i));
if(p.get(i)=="0"||p.get(i)=="1"||p.get(i)=="2"||p.get(i)=="3"||p.get(i)=="4"||p.get(i)=="5"||p.get(i)=="6"||p.get(i)=="7"||p.get(i)=="8"||p.get(i)=="9")
{
StringBuffer tn=new StringBuffer();
while(i<p.size()&&(p.get(i)=="0"||p.get(i)=="1"||p.get(i)=="2"||p.get(i)=="3"||p.get(i)=="4"||p.get(i)=="5"||p.get(i)=="6"||p.get(i)=="7"||p.get(i)=="8"||p.get(i)=="9"))
{
tn.append(p.get(i++));
}
System.out.println("This is the full number :"+tn);
stack.push(tn);
}
if(p.get(i)=="+"||p.get(i)=="-"||p.get(i)=="/"||p.get(i)=="*")
{
double a=Double.parseDouble(stack.pop().toString());
double b=Double.parseDouble(stack.pop().toString());
if(p.get(i)=="+")
{
stack.push(b+a);
}
else if(p.get(i)=="-")
{
stack.push(b-a);
}
else if(p.get(i)=="/")
{
stack.push(b/a);
}
else if(p.get(i)=="*")
{
stack.push(b*a);
}
}
}
System.out.println("Final value: "+stack);
return 0;
}
public static void main(String[] args) {
// TODO code application logic here
String s=new String("65*(79+22)-0/4+(29*5-6*(2*5))");
SampleInfixToPostfixToResult.result(SampleInfixToPostfixToResult.toPostfix(s));
//System.out.println(65*(79+22)-0/4+(29*5-6*(2*5)));
}
}
Solution:
1.Function toPostfix() now returns stack instead of vector, as now the postfix expression is added to the stack eg, [34,57.+] etc.
2.Edited the code for storing all the digits to the stack by traversing the string till we have a number.(see code till line no 29)
import java.util.Stack;
import java.util.Vector;
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author Sandeep
*/
public class Main {
static Stack stack=new Stack();
static Stack stackT=new Stack();
//static Vector v=new Vector();
//static StringBuffer p=new StringBuffer();
public static Stack toPostfix(String q)
{
for(int i=0;i<q.length();i++)
{
if(q.charAt(i)=='0'||q.charAt(i)=='1'||q.charAt(i)=='2'||q.charAt(i)=='3'||q.charAt(i)=='4'||q.charAt(i)=='5'||q.charAt(i)=='6'||q.charAt(i)=='7'||q.charAt(i)=='8'||q.charAt(i)=='9')
{
StringBuffer p=new StringBuffer();
while(q.charAt(i)=='0'||q.charAt(i)=='1'||q.charAt(i)=='2'||q.charAt(i)=='3'||q.charAt(i)=='4'||q.charAt(i)=='5'||q.charAt(i)=='6'||q.charAt(i)=='7'||q.charAt(i)=='8'||q.charAt(i)=='9')
p.append(q.charAt(i++));
stackT.push(p);
i--;
}
else if(q.charAt(i)=='(')
{
stack.push(q.charAt(i));
}
else if(q.charAt(i)==')')
{
for(int j=0;!stack.empty()&&!stack.peek().equals('(');j++)
{
stackT.push(stack.pop().toString());
}
stack.pop();
}
else if(q.charAt(i)=='+'||q.charAt(i)=='-'||q.charAt(i)=='/'||q.charAt(i)=='*')
{
if(stack.empty()||stack.peek().equals('('))
stack.push(q.charAt(i));
else
{
while(!stack.empty()&&!stack.peek().equals('(')&&isHigh(q.charAt(i), stack.peek()))
{
stackT.push(stack.pop().toString());
}
stack.push(q.charAt(i));
}
}
}
while(!stack.empty())
{
stackT.push(stack.pop().toString());
}
System.out.println(stackT);
return stackT;
}
//problem lies here
public static boolean isHigh(char op, Object AtStack)
{
char opAtStack=AtStack.toString().charAt(0);
boolean isHigh=false;
if((op==opAtStack))
isHigh=true;
if((op=='+'||op=='-')&&(opAtStack=='/'||opAtStack=='*'))
{
isHigh=true;
}
if((op=='+'&&opAtStack=='-')||(op=='-'&&opAtStack=='+')||(op=='/'&&opAtStack=='*')||(op=='*'&&opAtStack=='/'))
{
isHigh=true;
}
return isHigh;
}
public static double result(Stack p)
{
for(int i=0;i<p.size();i++)
{
if(p.get(i).toString().startsWith("0")||p.get(i).toString().startsWith("1")||p.get(i).toString().startsWith("2")||p.get(i).toString().startsWith("3")||p.get(i).toString().startsWith("4")||p.get(i).toString().startsWith("5")||p.get(i).toString().startsWith("6")||p.get(i).toString().startsWith("7")||p.get(i).toString().startsWith("8")||p.get(i).toString().startsWith("9"))
{
stack.push(p.get(i));
}
if(p.get(i).toString().equals("+")||p.get(i).toString().equals("-")||p.get(i).toString().equals("/")||p.get(i).toString().equals("*"))
{
double a=Double.parseDouble(stack.pop().toString());
double b=Double.parseDouble(stack.pop().toString());
if(p.get(i).equals("+"))
{
stack.push(b+a);
}
else if(p.get(i).equals("-"))
{
stack.push(b-a);
}
else if(p.get(i).equals("/"))
{
stack.push(b/a);
}
else if(p.get(i).equals("*"))
{
stack.push(b*a);
}
}
}
System.out.println(stack);
return 0;
}
public static void main(String[] args) {
// TODO code application logic here
String s=new String("159*(79+23)-10/4+(22*54-67*(25*58))");
Main.result(Main.toPostfix(s));
System.out.println(159*(79+23)-10/4+(22*54-67*(25*58)));
}
}