目录
一、问题分析
首先,项目是要实现基于栈的中缀算式表达式求值,要求循环输入一个以“=”结尾的中缀算术表达式,输出所求的表达式的值。
要解决此问题,我们可以按照以下步骤来实现:
- 建立栈,写出其基本操作
- 创建运算符栈和操作数栈
- 实现依次读取表达式中的字符,操作数入操作数栈,运算符入栈前要比较其优先级。当栈顶元素优先级小于新读取运算符的优先级,该运算符入栈;若优先级相等,则栈顶元素出栈,即去括号;当栈顶元素优先级大于新读取运算符的优先级,栈顶元素出栈,操作数依次出栈两个,与出栈的运算符进行计算之后将结果入操作数栈
- 最后操作数栈里的仅存的一个数就是表达式的结果
二、数据结构
1.逻辑结构
逻辑结构采用的是顺序栈
2.物理结构
static class SequenceStack<T>{
T[] stackArray;
int top;
static int defaultSize=20;
//栈的初始化
public SequenceStack(int n) {
stackArray=(T[])new Object[n];
top=-1;
}
public SequenceStack() {
this(defaultSize);
}
//入栈
public void push(T x) {
if(top==stackArray.length-1) {
T[]p=(T[])new Object[stackArray.length*2];
for(int i=0;i<=top;i++) {
p[i]=stackArray[i];
}
stackArray=p;
}
stackArray[++top]=x;
}
//出栈
public T pop() {
if(top==-1) {
System.out.print("栈为空,删除失败");
return null;
}
T x=stackArray[top--];
return x;
}
//获取栈顶元素
public T getTop() {
if(top==-1) {
System.out.print("栈为空,无法获取栈顶元素");
return null;
}
return stackArray[top];
}
//判断栈是否为空
public boolean isEmpty() {
return top==-1;
}
}
三、算法
1.栈类SequenceStack中的算法
(1)栈的初始化
public SequenceStack(int n) {
//强制转化初始化栈
stackArray=(T[])new Object[n];
top=-1;
}
public SequenceStack() {
//设置栈的空间的默认值
this(defaultSize);
}
(2)入栈
public void push(T x) {
//若栈满,增加空间令元素入栈;若栈不满,top值加一,指向最新的栈顶元素
if(top==stackArray.length-1) {
T[]p=(T[])new Object[stackArray.length*2];
for(int i=0;i<=top;i++) {
p[i]=stackArray[i];
}
stackArray=p;
}
stackArray[++top]=x;
}
(3)出栈
public T pop() {
//若栈为空,则无法使元素出栈;若栈不为空,栈顶元素出栈,随后top值减一指向新的栈顶元素
if(top==-1) {
System.out.print("栈为空,删除失败");
return null;
}
T x=stackArray[top--];
return x;
}
(4)获取栈顶元素
public T getTop() {
//若栈为空,则无法获取栈顶元素;若非空则返回top所指的元素即为栈顶元素
if(top==-1) {
System.out.print("栈为空,无法获取栈顶元素");
return null;
}
return stackArray[top];
}
(5)判栈空操作
public boolean isEmpty() {
//若栈空,top值等于-1
return top==-1;
}
2.主类text中的算法
(1)判定运算符优先级
public static boolean IsOperator(char c) {
//判定是否为规定的运算符
switch(c) {
case '=':
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':return true;
default:return false;
}
}
static char OP[][]= {
//用数组定义运算符的优先级表
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','#','E'},
{'>','>','>','>','E','>','>'},
{'<','<','<','<','<','E','#'}
};
public static int GetOperatorID(char Operator) {
//定义运算符下标,在数组中即可比较出彼此的优先级
switch(Operator) {
case '+':retCode=0;break;
case '-':retCode=1;break;
case '*':retCode=2;break;
case '/':retCode=3;break;
case '(':retCode=4;break;
case ')':retCode=5;break;
case '=':retCode=6;break;
}
return(retCode);
}
public static char Precede(char Operator1,char Operator2) {
//获取下标比较优先级
int OperatorID1,OperatorID2;
OperatorID1=GetOperatorID(Operator1);
OperatorID2=GetOperatorID(Operator2);
if(OperatorID1<0||OperatorID1>6||OperatorID2<0||OperatorID2>6) {
return('E');
}
return(OP[OperatorID1][OperatorID2]);
}
(2)运算法则
public static double Operate(double op1,char cal,double op2) {
//运算法则
switch(cal) {
case '+': return op1+op2;
case '-': return op1-op2;
case '*': return op1*op2;
case '/': return op1/op2;
default:return 0;
}
}
(3)读取操作数和运算符分别进栈
public static double ExpEvaluation(char []exp) {
//建立操作数栈和运算符栈,依次读取表达式中的字符,操作数入操作数栈,运算符入栈前要比较其优先级。当栈顶元素优先级小于新读取运算符的优先级,该运算符入栈;若优先级相等,则栈顶元素出栈,即去括号;当栈顶元素优先级大于新读取运算符的优先级,栈顶元素出栈,操作数依次出栈两个,与出栈的运算符进行计算之后将结果入操作数栈
SequenceStack<Character>OPTR=new SequenceStack<Character>();
SequenceStack<Double>OPND=new SequenceStack<Double>();
OPTR.push('=');
while(exp[i]!='='||OPTR.getTop()!='=') {
if(!IsOperator(exp[i])) {
String temp="";
while(!IsOperator(exp[i])&&i<exp.length) {
temp+=exp[i];
i++;
}
double result=Double.parseDouble(temp);
OPND.push(result);
}
else {
switch(Precede(OPTR.getTop(),exp[i])) {
case '<':
OPTR.push(exp[i]);
i++;
break;
case '#':
OPTR.pop();
i++;
break;
case '>':
thera=OPTR.pop();
b=OPND.pop();
a=OPND.pop();
OPND.push(Operate(a,thera,b));
break;
}
}
}
val=OPND.getTop();
return(val);
}
全部代码
package shiyan;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.*;
public class text {
public static boolean IsOperator(char c) {
switch(c) {
case '=':
case '+':
case '-':
case '*':
case '/':
case '(':
case ')':return true;
default:return false;
}
}
static char OP[][]= {
{'>','>','<','<','<','>','>'},
{'>','>','<','<','<','>','>'},
{'>','>','>','>','<','>','>'},
{'>','>','>','>','<','>','>'},
{'<','<','<','<','<','#','E'},
{'>','>','>','>','E','>','>'},
{'<','<','<','<','<','E','#'}
};
public static int GetOperatorID(char Operator) {
int retCode;
retCode=-1;
switch(Operator) {
case '+':retCode=0;break;
case '-':retCode=1;break;
case '*':retCode=2;break;
case '/':retCode=3;break;
case '(':retCode=4;break;
case ')':retCode=5;break;
case '=':retCode=6;break;
}
return(retCode);
}
public static char Precede(char Operator1,char Operator2) {
int OperatorID1,OperatorID2;
OperatorID1=GetOperatorID(Operator1);
OperatorID2=GetOperatorID(Operator2);
if(OperatorID1<0||OperatorID1>6||OperatorID2<0||OperatorID2>6) {
return('E');
}
return(OP[OperatorID1][OperatorID2]);
}
public static double Operate(double op1,char cal,double op2) {
switch(cal) {
case '+': return op1+op2;
case '-': return op1-op2;
case '*': return op1*op2;
case '/': return op1/op2;
default:return 0;
}
}
static class SequenceStack<T>{
T[] stackArray;
int top;
static int defaultSize=20;
public SequenceStack(int n) {
stackArray=(T[])new Object[n];
top=-1;
}
public SequenceStack() {
this(defaultSize);
}
public void push(T x) {
//栈满
if(top==stackArray.length-1) {
T[]p=(T[])new Object[stackArray.length*2];
for(int i=0;i<=top;i++) {
p[i]=stackArray[i];
}
stackArray=p;
}
stackArray[++top]=x;
}
public T pop() {
if(top==-1) {
System.out.print("栈为空,删除失败");
return null;
}
T x=stackArray[top--];
return x;
}
public T getTop() {
if(top==-1) {
System.out.print("栈为空,无法获取栈顶元素");
return null;
}
return stackArray[top];
}
public boolean isEmpty() {
return top==-1;
}
}
public static double ExpEvaluation(char []exp) {
char thera;
int i=0;
double b,a,val;
SequenceStack<Character>OPTR=new SequenceStack<Character>();
SequenceStack<Double>OPND=new SequenceStack<Double>();
OPTR.push('=');
while(exp[i]!='='||OPTR.getTop()!='=') {
if(!IsOperator(exp[i])) {
String temp="";
while(!IsOperator(exp[i])&&i<exp.length) {
temp+=exp[i];
i++;
}
double result=Double.parseDouble(temp);
OPND.push(result);
}
else {
switch(Precede(OPTR.getTop(),exp[i])) {
case '<':
OPTR.push(exp[i]);
i++;
break;
case '#':
OPTR.pop();
i++;
break;
case '>':
thera=OPTR.pop();
b=OPND.pop();
a=OPND.pop();
OPND.push(Operate(a,thera,b));
break;
}
}
}
val=OPND.getTop();
return(val);
}
public static void main(String[]args) {
for(;;) {
try {
BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
String s=br.readLine();
char[]us=s.toCharArray();
System.out.println(String.format("%.2f", ExpEvaluation(us)));
}catch(IOException e) {
e.printStackTrace();
}
}
}
}