在某些应用中,为了支持灵活性,往往用到自定义的公式。
比如,有如下的原始公式集合:
int add(int x, int y): 返回x与y的和
int add(int x, int y, int z): 返回x,y,z三个数的和
int min(int x, int y): 返回x,y中较小的值
int max(int x, int y): 返回x,y中较大的值
int doubleMe(int x): 返回 x 的2倍
给出一个自定义公式串
add(min(5,3),max(2,8),add(1,doubleMe(1)))
通过手工计算可以得出结果为:14
本题的任务是:编写一个解析程序,能够对由上述原始公式任意组合出来的公式计算其结果。也就是输入一个自定义公式串,输出它的计算结果(可以不考虑输入公式本身有语法错误的情况)。
输入的公式串中可以含有多余的空格,类似:
add( min(5, 3) , max(2 , 8) ) 也是合法的公式。
程序输入:公式串
程序输出:该公式的计算值
package com.liu.ex2;
import java.util.Scanner;
import java.util.Stack;
public class Main {
public static Stack<String> operation = new Stack<String>(); //存放运算符
public static Stack<Character> bracket = new Stack<Character>(); //存放左括号
public static Stack<Integer> number = new Stack<Integer>(); //存放运算参数
public static Stack<Integer> count = new Stack<Integer>(); //存放运算符参数个数
public int add(int[] N) {
if(N.length == 3)
return N[0] + N[1] + N[2];
return N[0] + N[1];
}
public int max(int[] N) {
return N[0] > N[1] ? N[0] : N[1];
}
public int min(int[] N) {
return N[0] < N[1] ? N[0] : N[1];
}
public int doubleMe(int[] N) {
return 2 * N[0];
}
public boolean judgeChar(char s) {
if(s >= 'a' && s <= 'z' || s >= 'A' && s <= 'Z')
return true;
return false;
}
public boolean judgeNumber(char s) {
if(s >= '0' && s <= '9')
return true;
return false;
}
public void getResult(String A) {
String temp = "";
for(int i = 0;i < A.length();i++) {
if(judgeChar(A.charAt(i))) {
temp = temp + A.charAt(i);
i = i + 1;
while(judgeChar(A.charAt(i))) {
temp = temp + A.charAt(i);
i++;
}
i = i - 1;
operation.push(temp);
count.push(0); //刚寻找到一个运算符,并初始化一个参数个数为0
temp = "";
} else if(A.charAt(i) == '(') {
bracket.push(A.charAt(i));
} else if(judgeNumber(A.charAt(i))) {
temp = temp + A.charAt(i);
i = i + 1;
while(judgeNumber(A.charAt(i))) {
temp = temp + A.charAt(i);
i++;
}
i = i - 1;
number.push(Integer.valueOf(temp));
count.push(count.pop() + 1); //此处用于计算当前栈顶运算符实际参数个数
temp = "";
} else if(A.charAt(i) == ')') { //此时要进行运算
bracket.pop(); //栈顶左括号出栈
String tempOpera = operation.pop();
int[] N = new int[count.pop()];
if(!count.empty())
count.push(count.pop() + 1);
for(int j = 0;j < N.length;j++)
N[j] = number.pop();
int result = 0;
if(tempOpera.equals("add"))
result = add(N);
else if(tempOpera.equals("max"))
result = max(N);
else if(tempOpera.equals("min"))
result = min(N);
else if(tempOpera.equals("doubleMe"))
result = doubleMe(N);
number.push(result);
}
}
}
public static void main(String[] args) {
Main test = new Main();
Scanner in = new Scanner(System.in);
String A = in.nextLine();
test.getResult(A);
System.out.println(number.pop());
}
}