基于栈的中缀算式表达式求值(Java实现)

一、问题分析

首先,项目是要实现基于栈的中缀算式表达式求值,要求循环输入一个以“=”结尾的中缀算术表达式,输出所求的表达式的值。
要解决此问题,我们可以按照以下步骤来实现:

  1. 建立栈,写出其基本操作
  2. 创建运算符栈和操作数栈
  3. 实现依次读取表达式中的字符,操作数入操作数栈,运算符入栈前要比较其优先级。当栈顶元素优先级小于新读取运算符的优先级,该运算符入栈;若优先级相等,则栈顶元素出栈,即去括号;当栈顶元素优先级大于新读取运算符的优先级,栈顶元素出栈,操作数依次出栈两个,与出栈的运算符进行计算之后将结果入操作数栈
  4. 最后操作数栈里的仅存的一个数就是表达式的结果

二、数据结构

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();
        	}
    	}  	
    }
}

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值