• nyoj35 表达式求值


    表达式求值

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:4
    描述
    ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧。
    比如输入:“1+2/4=”,程序就输出1.50(结果保留两位小数)
    输入
    第一行输入一个整数n,共有n组测试数据(n<10)。
    每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以“=”结束。这个表达式里只包含+-*/与小括号这几种符号。其中小括号可以嵌套使用。数据保证输入的操作数中不会出现负数。
    数据保证除数不会为0
    输出
    每组都输出该组运算式的运算结果,输出结果保留两位小数。

    样例输入

    2
    1.000+2/4=
    ((1+2)*5+1)/4=

    样例输出

    1.50
    4.00

    解答:

     
    import java.util.Scanner;
    import java.util.Stack;
    import java.text.DecimalFormat;
    
    public class Main{
    
    	public static void main(String[] args) {
    		DecimalFormat df=new DecimalFormat("#0.000");
    		
    		String[] exps=getInput();
    		
    		for(String s:exps){
    			s=convert(s);
    			//System.out.println(s);
    			double d=count(s);
    			String result=df.format(d);
    			result=result.substring(0,result.length()-1);
    			System.out.println(result);
    		}
    	}
    
    	/**
    	 * 接收输入
    	 * @return
    	 */
    	public static String[] getInput(){
    		Scanner scan=new Scanner(System.in);
    		int N=Integer.parseInt(scan.nextLine());
    		String[] exps=new String[N];
    		for(int i=0;i<N;i++){
    			exps[i]=scan.nextLine();
    		}
    		return exps;
    	}
    	/**
    	 * 转换为后缀表达式
    	 * @param exp 中缀表达式
    	 * @return
    	 */
    	public static String convert(String exp){
    		//存放转换后的后缀表达式
    		StringBuffer newExp=new StringBuffer();
    		//去处空格
    		exp=exp.replaceAll(" ", "");
    		//存放运算符的栈
    		Stack<String> sign=new Stack<String>();
    		//存放操作数
    		String num="";
    		//遍历中缀表达式
    		for(int i=0;i<exp.length();i++){
    			char c=exp.charAt(i);
    			if(c=='=')
    				break;
    			switch(c){
    			case '*':
    			case '/':
    				if(num.length()>0){
    					newExp.append(num+" ");
    					num="";
    				}
    				while(sign.size()>0){
    					String s=sign.pop();
    					if(s.equals("(")||s.equals("+")||s.equals("-")){
    						sign.push(s);
    						break;					
    					}else{
    						newExp.append(s+" ");
    					}
    				}
    				sign.push(c+"");
    				break;
    			case '(':
    				sign.push(c+"");
    				if(num.length()>0){
    					newExp.append(num+" ");
    					num="";
    				}
    				break;
    			case '+':
    			case '-':
    				if(num.length()>0){
    					newExp.append(num+" ");
    					num="";
    				}
    				while(sign.size()>0){
    					String s=sign.pop();
    					if(s.equals("(")){
    						sign.push(s);
    						break;					
    					}else{
    						newExp.append(s+" ");
    					}
    				}
    				sign.push(c+"");
    				break;
    			case ')':
    				if(num.length()>0){
    					newExp.append(num+" ");
    					num="";
    				}
    				while(sign.size()>0){
    					String s=sign.pop();
    					if(s.equals("("))
    						break;
    					newExp.append(s+" ");
    				}
    				break;
    			default:
    				num+=c;
    			}
    		}
    		if(num.length()>0){
    			newExp.append(num+" ");
    			num="";
    		}
    		while(sign.size()>0){
    			newExp.append(sign.pop()+" ");
    		}
    		
    		return newExp.toString();
    	}
    	/**
    	 * 计算后缀表达式的值
    	 * @param exp 后缀表达式
    	 * @return 结果
    	 */
    	public static double count(String exp){
    		String[] ss=exp.split(" ");
    		//存放操作数
    		Stack<Double> nums=new Stack<Double>();
    		//遍历后缀表达式
    		for(String s:ss){
    			//遇到运算符时
    			if(s.length()==1&&!Character.isDigit(s.charAt(0))){
    				//取出前面的两个操作数
    				double b=nums.pop();
    				double a=nums.pop();
    				//判断符号,进行运算,再加入栈中
    				if("+".equals(s))
    				{
    					nums.push(a+b);
    				}
    				else if("-".equals(s))
    				{
    					nums.push(a-b);
    				}
    				else if("*".equals(s))
    				{
    					nums.push(a*b);
    				}
    				else if("/".equals(s))
    				{
    					nums.push(a/b);
    				}
    			}else{
    				//遇到操作数时
    				nums.push(Double.parseDouble(s));
    			}
    		}
    		
    		return nums.pop();
    	}
    }
            

    原题链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=35


    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    java基础语法
    java 设计模式
    Mysql或者SQL Server数据库的运行机制和体系架构
    数据库中间件
    Spring的工作原理
    Hibernate和Mybatis的工作原理以及区别
    SpringMVC
    HTML学习笔记(八) Web Worker
    HTML学习笔记(七) Web Storage
    HTML学习笔记(六) 元素拖放
  • 原文地址:https://www.cnblogs.com/Jayme/p/4902364.html
Copyright © 2020-2023  润新知