java_表达式求值_异常处理

题目描述
输入:首先输入变量类型 和变量名称,使用换行或者;分割不同变量定义,可以使用=为变量赋值。最后输入一个包含变量的表达式
支持的运算包括:+,-,*,/和%以及()。整数与整数运算返回整数,整数与小数运算返回小数。和Java编译器表达式一致。
输出:输出表达式的值。如果结果为小数则保留2位小数。
如果表达式错误,则输出wrong - error expression
变量未定义,则输出 wrong - variable undefined
变量未赋初值,则输出 wrong - variable unassigned
示例:
 输入:
 int i;
 int j;
 i=10;
 j=20;
 i*2+j=?
 输出:40
样例输入输出
样例1
输入:
int a=21;
int b=2;
float c=11;
a/b+c=?
输出:
21.00
样例2
输入:
float a=21;
int b=2;
float c=11;
a/b+c=?
输出:
21.50
输入:
float a=21;
int b=2;
float c=11;
a/m+c=?
输出:
wrong - variable undefined
输入:
float a=21;
int b=2;
float c=11;
(a/b+c=?
输出:
wrong - error expression*/

import java.util.*;
import java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.Stack;

public class Main {
    List<String>tokens=new ArrayList<>();
    static Stack<String>operators = new Stack<>();
    static Stack<String>type_number=new Stack<>();
    static ArrayList<String> stringList1 = new ArrayList<>();
    static ArrayList<String> stringList = new ArrayList<>();         
    static Map<String, String> v0 = new HashMap<>();
    static Map<String, String> v1 = new HashMap<>();
    static Map<String, String> v2 = new HashMap<>();

    static int precedence(String op)
    {
        switch (op) {
            case "+": case "-": return 1;
            case "*": case "/": case "%": return 2;
            default: return -1;
        }
    }

    static String evaluate(String expression, Map<String, String> variables)
            throws Exception {

        Pattern tokenPattern = Pattern.compile("(int|float)\\d+(\\.\\d+)?|[+\\-*/%()]");
        Matcher matcher = tokenPattern.matcher(expression);
        while (matcher.find()) {              
            String token = matcher.group();
            if (token.matches("(int|float)\\d+(\\.\\d+)?"))   
                type_number.push(token);                     
            else if (token.equals("("))       
                    operators.push(token);
            else if (token.equals(")"))
            {
                while (!operators.isEmpty() && !operators.peek().equals("("))
                    executeOperation(operators,type_number);
                operators.pop();
            }
            else if (Arrays.asList("+", "-", "*", "/", "%").contains(token))
            {
                while
                (!operators.isEmpty()&&precedence(operators.peek()) >= precedence(token))
                    executeOperation(operators,type_number);
                operators.push(token);

            } else
                throw new Exception("wrong - error expression");
        }

        while (!operators.isEmpty()) 
            executeOperation(operators,type_number);           
        if (type_number.size() != 1) {
            throw new Exception("wrong - error expression");
        }
        return type_number.pop();
    }

    static void executeOperation(Stack<String> operators, Stack<String>type_number)
            throws Exception{
        String op = operators.pop();
        String b1=type_number.pop();
        String a1=type_number.pop();
        double a=0,b = 0,result = 0;
        String b2,a2,result_String;
        {
            if(b1.charAt(0)=='i')
            {
                b2= b1.replaceAll("\\Q" +"int" + "\\E", "");
                b=Double.parseDouble(b2);
                b=(int)b;
            }
            else if(b1.charAt(0)=='f')
            {
                b2= b1.replaceAll("\\Q" + "float"+ "\\E", "");
                b=Double.parseDouble(b2);
            }


            if(a1.charAt(0)=='i')
            {
                a2= a1.replaceAll("\\Q" +"int"+ "\\E", "");
                a=Double.parseDouble(a2);
                a=(int)a;
            }
            else if(a1.charAt(0)=='f')
            {
                a2= a1.replaceAll("\\Q" +"float"+ "\\E", "");
                a=Double.parseDouble(a2);
            }

        }
        if(a1.charAt(0)=='i'&&b1.charAt(0)=='i')
                    result=(int)result;                          
        switch (op) {
            case "+": 
                    result = a + b;                     
                    break;                   
            case "-": 
                    result = a - b;                      
            break;          
            case "*":             
                    result = a * b; 
                    break;
            case "/":
                if (b == 0) throw new Exception("wrong - error expression");
                result = a / b; break;
            case "%":
                if (b == 0) throw new Exception("wrong - error expression");
                result = a % b; break;
            default: throw new Exception("wrong - error expression");
        }
        result_String = String.valueOf(result);
        if(a1.charAt(0)=='i'&&b1.charAt(0)=='i')
            type_number.push("int"+result_String);
            else if(a1.charAt(0)=='f'||b1.charAt(0)=='f')
            type_number.push("float"+result_String);          
    }

    static void executeInput(String input) {
        if (input.trim().isEmpty())return;
        Pattern pattern = Pattern.compile("^(float|int)\\s+(\\w+)\\s*=\\s*(.+);$");
        Matcher matcher = pattern.matcher(input);      
        if (matcher.find()) {
            String type = matcher.group(1);
            String name = matcher.group(2);
            String valueStr = matcher.group(3).trim();
            String type_value=type+valueStr;      
                v0.put(name, type_value);//a-int10
        }
        else {String type=null,name=null,valueStr =null;
                if(input.substring(0,2).equals("in")) {                       
                                name=input.substring(4,input.length()-1);
                                type="int";
                                v1.put(name, type);
                    }
                if(input.substring(0,2).equals("fl")) {                       
                                    name=input.substring(6,input.length()-1);        
                                    type="float";
                                    v1.put(name, type);
                                    }
                if(input.charAt(1)=='=')
                {
                name=input.substring(0,1);
                valueStr=input.substring(2,input.length()-1);
                v2.put(name, valueStr);
                }           
    }      
 }

    static void calculate(String exp,String exp1) {     
        try {      
            String result_str1 = null;
            String result_str = evaluate(exp,v0);      
            char op=result_str.charAt(0);
            switch (op) {
            case 'f': 
                    result_str1= result_str.replaceAll("\\Q" + "float" + "\\E", "");                 
                    break;                   
            case 'i': 
                    result_str1= result_str.replaceAll("\\Q" + "int" + "\\E", "");                 
            break;                     
            default:
        }                     
            double result=Double.parseDouble(result_str1);
            if(op=='f')System.out.printf("%.2f%n", result);
            if(op=='i')System.out.println((int)result);
        }catch (Exception e) {               
        	 System.out.println("wrong - error expression");
        }
    }

      public static void main(String[] args) {
        String exp=null;
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNextLine())
        {
            String input = scanner.nextLine().trim();
            char lastChar=input.charAt(input.length()-1);
            if (lastChar=='?')
            {
                exp=input;
                break;
            }
            executeInput(input);
        }
        
        String exp1=exp;
        if (exp1.endsWith("=?"))
        exp1= exp1.substring(0, exp1.length() - 2);
        
        int map=0,map1=0;
        int tap=0,tap1=0;
        String[] Key1= new String[v1.entrySet().size()]; 
        String[] Value1= new String[v1.entrySet().size()];
        String[] Key2= new String[v2.entrySet().size()]; 
        String[] Value2= new String[v2.entrySet().size()];
        
        for (Map.Entry<String, String> entry : v1.entrySet()) 
        {
            Key1[map++]=entry.getKey();
            Value1[map1++]= entry.getValue();  
        }
        for (Map.Entry<String, String> entry : v2.entrySet()) 
        {
            Key2[tap++]=entry.getKey();
            Value2[tap1++]= entry.getValue();
        }
        
        for(int i=0;i<v1.entrySet().size();i++) 
                for(int j=0;j<v2.entrySet().size();j++) 
                if(Key1[i].equals(Key2[j])) 
                {
                Value1[i]=Value1[i]+Value2[j];
                v0.put(Key1[i], Value1[i]);
                }
        for (Map.Entry<String, String> entry : v0.entrySet())
        {
            String str= Pattern.quote(entry.getKey());
            exp= exp.replaceAll(str, entry.getValue());
        }
     
        for(int i=0;i<exp.length();i++)
        {
                char op=exp.charAt(i);
                switch (op) {
              case '1': case '2': 
              case '3': case '4': 
              case '5': case '6': 
              case '7': case '8': case '9': 
              case '0':
              for(int j=i+1;j<exp.length();j++) {
                     if(
                                    (exp.charAt(j)=='('
                                         ||exp.charAt(j)=='+'
                                        ||exp.charAt(j)=='-'
                                        ||exp.charAt(j)=='*'
                                        ||exp.charAt(j)=='/'
                                        ||exp.charAt(j)=='%'
                                        ||exp.charAt(j)==')'
                                        ||exp.charAt(j)=='=')
                    &&(exp.charAt(i-1)=='('
                                 ||exp.charAt(i-1)=='+'
                                ||exp.charAt(i-1)=='-'
                            ||exp.charAt(i-1)=='*'
                                ||exp.charAt(i-1)=='/'
                                ||exp.charAt(i-1)=='%'
                                ||exp.charAt(i-1)==')'
                                ||exp.charAt(i-1)=='='
                                ||i==1
                                    )
                           ) 
                     {
                    String tp=exp.substring(i,j);
                    boolean tp1=true;
                    for(int k=0;k<tp.length();k++) 
                            if(tp.charAt(k)=='.')
                            {tp1=false;break;}
                    if(tp1) 
                            exp=exp.replaceAll(tp,"int"+tp);                                                         
                    else if(!tp1)
                            exp=exp.replaceAll(tp,"float"+tp); 
                    i=j;
                    break;
                     }
              }              
          }
        }
        
        for (Map.Entry<String, String> entry : v0.entrySet()) 
        {
            String key = entry.getKey();
            stringList1.add(key);
        }
        
        String exp2=exp.replaceAll("float",""); 
               exp2=exp2.replaceAll("int","");
      
       for(int i=0;i<exp2.length();i++) 
                {char op=exp2.charAt(i);
                if(
                    (op>=65&&op<=90)
                    ||
                    (op>=97&&op<=122))
                { String sub=exp2.substring(i,i+1);
                boolean tmp=true;
                for(int j=0;j<Key1.length;j++) 
                	if(sub.contentEquals(Key1[j]))
                	{
                		tmp=false;break;
                	}
                
                if(tmp)
                        {System.out.println("wrong - variable undefined");
                        return;}
                else {
                	System.out.println("wrong - variable unassigned");
                    return;
                }
                }        
                }
      
        if (exp.endsWith("=?"))
            exp= exp.substring(0, exp.length() - 2);
        calculate(exp,exp1);
        scanner.close();
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值