主要要理解后缀表达式是怎么由中缀表达式得来的
多写写算术表达式实际是怎么运算的(顺序)
后缀表达式是怎么运算的
使用(来提升运算符的优先级
运算符总是跟在第二个操作元的后面
package Evaluation;
import java.util.Scanner;
class Stack
{
final int MaxSize = 10;
char[] data = new char[MaxSize];
int top;
public Stack()
{
top = -1;
}
}
// 运算符优先级
class Priority
{
final int MaxOp = 7;
final char[] ch = { '=', '(', '+', '-', '*', '/', ')' }; // 运算符
final int[] lpri = { 0, 1, 3, 3, 5, 5, 6 }; // 左运算符优先级
final int[] rpri = { 0, 6, 2, 2, 4, 4, 1 }; // 右运算符优先级
}
public class Main
{
public static void main(String args[])
{
Scanner cin = new Scanner(System.in);
String exp = cin.nextLine();
exp = exp + "\0";
char postexp[] = new char[30];
trans(exp, postexp);
System.out.println("中缀表达式:" + exp);
int i = 0;
char ch = postexp[i];
while (ch != '\0')
{
System.out.print(ch);
ch = postexp[++i];
}
System.out.println();
System.out.println("表达式的值:" + compvalue(postexp));
}
// 判断是否为运算符
public static boolean IsOp(char ch)
{
Priority pri = new Priority();
for (int i = 0; i < pri.MaxOp; i++)
if (ch == pri.ch[i])
return true;
return false;
}
// 求左运算符op的优先级
public static int leftpri(char op)
{
Priority pri = new Priority();
for (int i = 0; i < pri.MaxOp; i++)
if (op == pri.ch[i])
return pri.lpri[i];
return 0;
}
// 求右运算符op的优先级
public static int rightpri(char op)
{
Priority pri = new Priority();
for (int i = 0; i < pri.MaxOp; i++)
if (op == pri.ch[i])
return pri.rpri[i];
return 0;
}
// 返回op1与op2运算符优先级的比较结果
public static int Precede(char op1, char op2)
{
if (leftpri(op1) == rightpri(op2))
return 0;
else if (leftpri(op1) < rightpri(op2))
return -1;
else
return 1;
}
// 将算术表达式exp转换成后缀表达式postexp
public static void trans(String exp, char[] postexp)
{
int i = 0;
Stack Sop = new Stack();
Sop.top++;
Sop.data[Sop.top] = '='; // 将'='入栈
int n = 0;
char ch = exp.charAt(n);
while (ch != '\0')
{
if (!IsOp(ch))
{
while (ch >= '0' && ch <= '9')
{
postexp[i++] = ch;
ch = exp.charAt(++n);
}
postexp[i++] = '#';
}
else
{
switch (Precede(Sop.data[Sop.top], ch))
{
case -1: // 栈顶运算符优先级低
Sop.data[++Sop.top] = ch;
ch = exp.charAt(++n); // 继续扫描其他字符
break;
case 0: // 只有括号满足这种情况
Sop.top--; // 退栈
ch = exp.charAt(++n); // 继续扫描其他字符
break;
case 1:
postexp[i++] = Sop.data[Sop.top--]; // 退栈并输出到postexp中
break;
}
}
}
while (Sop.data[Sop.top] != '=')
{
postexp[i++] = Sop.data[Sop.top--];
}
postexp[i] = '\0';
}
// 计算后缀算数表达式
public static float compvalue(char[] postexp)
{
Stack st = new Stack();
float d, a, b, c;
int i = 0;
char ch = postexp[i];
while (ch != '\0')
{
switch (ch)
{
case '+':
a = st.data[st.top--];
b = st.data[st.top--];
c = b + a;
st.data[++st.top] = (char) c;
break;
case '-':
a = st.data[st.top--];
b = st.data[st.top--];
c = b - a;
st.data[++st.top] = (char) c;
break;
case '*':
a = st.data[st.top--];
b = st.data[st.top--];
c = b * a;
st.data[++st.top] = (char) c;
break;
case '/':
a = st.data[st.top--];
b = st.data[st.top--];
if (a != 0)
{
c = b / a;
st.data[++st.top] = (char) c;
} else
{
System.out.println("除0错误");
}
break;
default:
d = 0;
while (ch >= '0' && ch <= '9')
{
d = 10 * d + (ch - '0');
ch = postexp[++i];
}
st.data[++st.top] = (char) d;
break;
}
ch = postexp[++i];
}
return st.data[st.top];
}
}
输入:
1+3*2-1
输出:
中缀表达式:1+3*2-1
1#3#2#*+1#-
表达式的值:6.0
输入:
(56-20)/(4+2)
输出:
中缀表达式:(56-20)/(4+2)
56#20#-4#2#+/
表达式的值:6.0