栈的应用--四则表达式

本文详细介绍了栈数据结构在四则运算表达式求值过程中的作用,包括将中缀表达式转换为后缀表达式,以及利用栈进行后缀表达式的计算。通过具体代码实现,展示了栈如何简化程序设计问题,提高解决问题的效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有人可能会觉得,用数组或链表直接实现功能不就可以了吗?为什么还要引入栈这种数据结构呢?

其实栈的引入简化了程序设计的问题,划分了不同关注层次,使得思考范围缩小,更加聚集于我们要解决的问题核心。他封装了一些方法,使得我们使用这些方法的时候不需要考虑里面的细节问题,而只需要考虑如何用这种结构解决问题。

栈的应用:

1、递归问题(用栈来管理函数的调用,这在高级语言中系统已经帮我们管理了,我们不用操心这个问题)

2、四则运算表达式求值

代码实现如下:

package seqList;

import java.util.ArrayList;
/*
 * 要想让计算机具有处理我们通常的标准(中缀)表达式的能力,最重要的就是两步:
 * 1、将中缀表达式转化为后缀表达式
 * 2、将后缀表达式进行运算得出结果
 */
//前面的三个函数是为了将字符串转化为字符串数组
public class Arithmetic {

    // 判断是否为操作符
	public boolean isOpe(String s) {
		String[] ope=new String[]{"+","-","*","/","(",")"};
		for(int i=0;i<ope.length;i++) {
			if(s.equals(ope[i])) {
				return true;
			}
		}
		return false;
	}
	//判断是否为数字
	public boolean isDigit(char c){
		if(c>='0'&&c<='9'){
			return true;
		}
		return false;
	}
	//将字符串转化为字符串数组
	public ArrayList<String> transtion(String s){
		ArrayList<String> list=new ArrayList<>();
		char[] chr=s.toCharArray();
		StringBuilder sb=new StringBuilder();
		for(int i=0;i<chr.length;i++) {
			if(isDigit(chr[i])) {
				sb.append(chr[i]);
			}
			else {
				if(sb.toString().length()>0) {
					list.add(sb.toString());
					sb.delete(0, sb.toString().length());
				}
				list.add(chr[i]+"");
			}
		}
		if(sb.toString().length()>0) {
			list.add(sb.toString());
			sb.delete(0, sb.toString().length());
		}
		for(int i=0;i<list.size();i++) {
			System.out.print(list.get(i));
		}
		System.out.println();
		return list;
	}
    //中缀表达式转后缀表达式
	public ArrayList<String> InfixToPostfix(ArrayList<String> s) throws Exception {
		ArrayList<String> postfixList=new ArrayList<>();//存储后缀表达式
		LinkStack stack=new LinkStack();//存储操作符
	    for(int i=0;i<s.size();i++) {
	    	//如果是( 则进栈
	    	if(s.get(i).equals("(")) {
	    		stack.push(s.get(i));
	    	}
	    	//如果是*或者除号/也进栈
	    	else if(s.get(i).equals("*")||s.get(i).equals("/")) {
	    		stack.push(s.get(i));
	    	}
	    	/*当符号是+或者-时,它们已经是优先级最低的符号了
	    	 * 
	    	 * 1、如果栈不为空,但栈顶元素是( 时,入栈
	    	 * 2、如果不是,栈顶元素出栈,放到后缀表达式中
	    	 */
	    	//这块一直出错,当Stack不为空时,如果没有左括号是要一直出栈,知道栈为空,所以此时s.get(i)是要进栈的
	    	else if(s.get(i).equals("+")||s.get(i).equals("-")) {
	    		 //如果栈不为空的话
	    			while(!stack.isEmpty()) {
		    			//先判断栈顶元素是否为( ,若是入栈
		    			if(stack.getTop().equals("(")) {
		    				stack.push(s.get(i));
		    				break;
		    				}
		    			//若不是,栈顶元素出栈
		    			else {
		    				postfixList.add((String)stack.pop());
		    			}
		    		}
	    		//栈空,将该元素入栈
	    		if(stack.isEmpty())
	    			stack.push(s.get(i));
	    		
	    		
	    	}
	    	else if(s.get(i).equals(")")){
	    		while(!stack.getTop().equals("(")) {
	    			postfixList.add((String)stack.pop());
	    		}
	    		stack.pop();//将( 出栈
	    	}
	    	else {
	    		postfixList.add(s.get(i));
	    	}
	    }
	    while(!stack.isEmpty()) {
	    	postfixList.add((String)stack.pop());
	    }
	    for(int i=0;i<postfixList.size();i++) {
	    	System.out.print(postfixList.get(i));
	    }
	    return postfixList;
		
	}
	//将后缀表达式进行运算得出结果
	public int calculate(ArrayList<String> postfixList) throws Exception {
		LinkStack stack=new LinkStack();//暂时存储还没有计算的数和操作符
		for(int i=0;i<postfixList.size() ;i++) {
			if(!isOpe(postfixList.get(i))) {
				stack.push(Integer.parseInt(postfixList.get(i)));
			}
			else {
				if(postfixList.get(i).equals("+")) {
					int sum=(int)stack.pop()+(int)stack.pop();
					stack.push(sum);
				}
				if(postfixList.get(i).equals("-")) {
					int x=(int)stack.pop();
					int y=(int)stack.pop();
					int sum=y-x;
					stack.push(sum);
				}
				if(postfixList.get(i).equals("*")) {
					int sum=(int)stack.pop()*(int)stack.pop();
					stack.push(sum);
				}
				if(postfixList.get(i).equals("/")) {
					int x=(int)stack.pop();
					int y=(int)stack.pop();
					int sum=y/x;
					stack.push(sum);
				}
			}
		}
		return (int)stack.pop();
	}
	
	
//测试代码
	public static void main(String[] args) throws Exception {
		Arithmetic ari=new Arithmetic();
		String  str = "9+(3-1)*3+10/2";
		ArrayList<String> list = ari.transtion(str);
		ArrayList<String> list1= ari.InfixToPostfix(list);
		System.out.println();
		System.out.println(ari.calculate(list1));
	}

}

运行结果:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值