中缀表达式转逆波兰表达式程序及逆波兰表达式计算器实现

本文介绍了将中缀表达式转换为逆波兰表达式的方法,包括初始化两个栈,按顺序处理数字和运算符,处理括号等步骤。同时,概述了逆波兰表达式计算器的工作原理,通过扫描表达式,存储数字,计算运算符得到最终结果。

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

中缀表达式转后缀表达式步骤:
(1)初始两个栈:运算符栈s1 存储中间结果的栈s2
(2)从左往右扫描中缀表达式
(3)遇数 直接压入栈s2
(4)遇运算符:
a、如果s1为空或栈顶运算符号为 “ ( ”,直接将其压入栈s1
b、如果运算符的优先级比s1栈顶元素的优先级高,将运算符压入栈s1
c、如果运算符的优先级小于等于栈顶元素运算符,将栈顶元素弹出并压入栈s2 再次转到(4)的操作
(5)遇到括号:
a、左括号直接入栈s1
b、右括号 依次弹出s1栈顶的运算符并将其压入栈s2,直到遇到左扩号为止,将左括号弹出,此时完成对这一对扩号的丢弃
(6)重复2-5操作 直至遍历完中缀表达式
(7)将s1中剩余的运算符依次弹出并压入s2
(8)依次弹出s2中的元素并输出,结果的逆序即为中缀表达式的后缀表达式的形式

逆波兰计算器

  • 1、逆波兰表达式》》从左往右依次扫描 —遇到数字存入栈中,遇到运算符,依次弹出栈顶和次栈顶元素计算结果,将结果存入栈中 —遍历结束,栈中只有一个元素即为最终的结果
//将字符串转换成中缀表达式
    public static  List<String> toMPoland(String str){
    	char[] c=str.toCharArray(); //字符串转成字符数组,遍历字符数组转成 list 
    	String s; //对多位数的拼接
    	ArrayList<String> list=new ArrayList<String>();
    	for(int i=0;i<c.length;i++) {
    		if(c[i]<48||c[i]>57) {  //如果是一个运算符  (注:每一个字符都有对应的ASCII值)
    			list.add(""+c[i]); //直接添加到list中  (注;字符转字符串的方法)
    			
    		}else {   //若果是一个数  不能直接存入list 因为要考虑它后面是否还是数字
    			s="";  
    			while((i<c.length)&&((c[i]>=48)&&(c[i]<=57))){  //判断i的下一位是否是数字 如果是添加在之前的数字后面 
    				s+=c[i];  //多位数的拼接
    				i++;
    			}
    			i--;  //直到条件不满足  即c[i]不为数  由于在进入整个大的for循环之前,i会自动加1 所以此处需将i-1  
    			list.add(s); //将得到的多位数加入到list中
    		}
    	}
		return list;
    }
    
    //运算符的优先级的比较    
    public static  int priority(String str) {
    	if(str.equals("*")||str.equals("/")) {
    		return 2;
    	}else {
    		return 1;
    	}
    }
    
   //将中缀表达式转成后缀表达式
    public static List<String> toRevPoland(List<String> list){
    	
    	//存放运算符号的栈
    	Stack<String> s1=new Stack<String>();
    	//分析的时候 是一个数栈 但由于在此处数只需要存入而不需要弹出 所以可以用List代替数栈
    	List<String> s2=new ArrayList<>();
    	 for(int i=0;i<list.size();i++) {
    		 
    		 String element=list.get(i);
    		 
    		if(element.matches("\\d+")) {  //如果是一个数 直接存入数组中   !!!利用了正则表达式
    			s2.add(element);
    		}else   //如果是一个运算符
    		 //遇到左括号
    		if(element.equals("(")) {        //左扩号直接入栈
    			s1.push("(");
    		}else if(element.equals(")")) {  //遇到右扩号
    			while(!s1.peek().equals("(")) {
    				s2.add(s1.pop());       
    			}
    			s1.pop();   //将对应的左扩号丢弃
    		}else if(s1.isEmpty()||s1.peek().equals("(")) {  //如果s1栈为空 或栈顶元素为左括号“(”
    			s1.push(element);   //直接将运算符入栈
    		}else {
    			while((s1.size()!=0)&&priority(s1.peek())>=priority(element)) { //如果s1不为空且栈顶运算符的优先级大于等于遍历的运算符的优先级
    				s2.add(s1.pop());  //弹出栈顶元素 将其压入s2
    			}
    			s1.push(element);  
    		}
    	 }
    	  
    	 while(s1.size()!=0) {
    		 s2.add(s1.pop());
    	 }
    	 
    	 return s2; //由于s2是ArrayList 所以结果就是逆波兰表达式
    }
    
    //逆波兰表达式计算器 
    public static void calculate(List<String> list) {
    	int num1=0;
		int num2=0;
		int res=0;
    	Stack<String> stack=new Stack<>();
    	for(String e:list) {   //如果是数字  入栈
    		if(e.matches("\\d+")) { //匹配的是多位数
    			stack.push(e);
    		}else {  //如果是符号  从栈中弹出两位数 进行对应的计算 然后再将其存入栈中
    			if(e.equals("+")) {
    			  num1=Integer.parseInt(stack.pop());
      			  num2=Integer.parseInt(stack.pop());
    			  res=num1+num2;
    			  
    			  
    			} else if (e.equals("-")){
    				num1=Integer.parseInt(stack.pop());
        			num2=Integer.parseInt(stack.pop());
      			    res=num2-num1;
    			}else if(e.equals("*")) {
    				num1=Integer.parseInt(stack.pop());
        			num2=Integer.parseInt(stack.pop());
      			    res=num2*num1;
    			}else if(e.equals("/")) {
    				num1=Integer.parseInt(stack.pop());
        			num2=Integer.parseInt(stack.pop());
      			    res=num2/num1;
    			}else {  //如果不是数也不是运算符  将抛出异常
    				throw new RuntimeException();
    			}
    			stack.push(""+res);	
    		}
    	}
    	System.out.println("计算的结果是:"+Integer.parseInt(stack.pop()));  //计算到最后 栈中只有一个元素 即为最终的运算结果
    }
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值