Java 四则运算表达式求解(二)

2014-11-24 03:11:03 · 作者: · 浏览: 2
turn "缺少右括号";

s3.push(s4.pop());

}

return count_result(s3);

}

private int priorityCompare(char c1,char c2)

{

switch(c1)

{

case '+':

case '-':

return (c2 == '*' || c2 == '/' -1 : 0);

case '*':

case '/':

return (c2 == '+' || c2 == '-' 1 : 0);

}

return 1;

}

//判断字符是否为运算符,是为真,不是为假

private boolean isOprator(Object c) {

// TODO Auto-generated method stub

try

{

char c1=(char)c;

if(c1=='+'||c1=='-'||c1=='*'||c1=='/'||c1=='('||c1==')')

return true;

}

catch (Exception e) {

// TODO: handle exception

return false;

}

return false;

}

private String count_result(Stack ob) {

// TODO Auto-generated method stub

Stack s1=new Stack();//后缀表达式栈

Stack s2=new Stack();//操作数栈

//char c1;

// Stack s3=new Stack();//操作符栈

while(!ob.isEmpty())//将传入的栈逆序压入

{

s1.push(ob.pop());

}

while(!s1.isEmpty())

{

if(!isOprator(s1.peek()))//遇到非操作符,压入s2栈

{

s2.push((Double)s1.pop());

}

else

{

s2.push(cout(s2.pop(),s2.pop(),(char)s1.pop()));

}

}

return Double.toString(s2.peek());

}

private Double cout(double s1,double s2,char s3)

{

double result=0;

switch(s3)

{

case '+':

result=s1+s2;

break;

case '-':

result=s1-s2;

break;

case '*':

result=s1*s2;

break;

case '/':

result=s1/s2;

break;

}

return result;

}

代码全部在上面,只有一个Public函数够调用者访问,其余函数全为Private。

实现思路

采用将中缀表达式先转换成后缀表达式,然后再用基本的表达式求法对简化后的表达式求解(具体中缀表达式和后缀表达式的区别请参见博客http://blog.csdn.net/antineutrino/article/details/6763722,在此要感谢该博客博主。)

1.中缀表达式转化为后缀表达式

(1) 初始化两个栈:运算符栈S1和储存中间结果的栈S2;

(2) 从左至右扫描中缀表达式;

(3) 遇到操作数时,将其压入S2;

(4) 遇到运算符时,比较其与S1栈顶运算符的优先级:

(4-1) 如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;

(4-2) 否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);

(4-3) 否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;

(5) 遇到括号时:

(5-1) 如果是左括号“(”,则直接压入S1;

(5-2) 如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;

(6) 重复步骤(2)至(5),直到表达式的最右边;

(7) 将S1中剩余的运算符依次弹出并压入S2;

(8) 依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。

例如,将中缀表达式“1+((2+3)×4)-5”转换为后缀表达式的过程如下:

扫描到的元素 S2(栈底->栈顶) S1 (栈底->栈顶) 说明

1 1 空 数字,直接入栈

+ 1 + S1为空,运算符直接入栈

( 1 + ( 左括号,直接入栈

( 1 + ( (同上

2 1 2 + ( (数字

+ 1 2 + ( ( + S1栈顶为左括号,运算符直接入栈

3 1 2 3 + ( ( + 数字

) 1 2 3 + + ( 右括号,弹出运算符直至遇到左括号

× 1 2 3 + + ( × S1栈顶为左括号,运算符直接入栈

4 1 2 3 + 4+ ( × 数字

) 1 2 3 + 4 × + 右括号,弹出运算符直至遇到左括号

- 1 2 3 + 4 ×+ - -与+优先级相同,因此弹出+,再压入-

5 1 2 3 + 4 ×+ 5 - 数字

到达最右端 1 2 3 + 4 ×+ 5 -空 S1中剩余的运算符

因此结果为“1 2 3 + 4 ×+ 5 -”(注意需要逆序输出)。

2.计算后缀表达式

从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。

例如后缀表达式“3 4 + 5 ×6 -”:

(1) 从左至右扫描,将3和4压入堆栈