题目描述
输入:首先输入变量类型 和变量名称,使用换行或者;分割不同变量定义,可以使用=为变量赋值。最后输入一个包含变量的表达式
支持的运算包括:+,-,*,/和%以及()。整数与整数运算返回整数,整数与小数运算返回小数。和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();
}
}