Java 数学表达式解析器
我从Dreamincode论坛找到了数学表达式解析器的代码 我的问题是,在这段代码上,我认为一切都很顺利,但是当我有一个测试用例(2(3+5))时,这是有效的,而这个测试用例是完全错误的 但是如果我给出测试用例(3+5)2),它被检测为无效输入。 有人知道为什么会这样吗Java 数学表达式解析器,java,parsing,Java,Parsing,我从Dreamincode论坛找到了数学表达式解析器的代码 我的问题是,在这段代码上,我认为一切都很顺利,但是当我有一个测试用例(2(3+5))时,这是有效的,而这个测试用例是完全错误的 但是如果我给出测试用例(3+5)2),它被检测为无效输入。 有人知道为什么会这样吗 //enum for Operator "objects" import java.util.*; public enum Operator { ADD("+", 1) { double do
//enum for Operator "objects"
import java.util.*;
public enum Operator {
ADD("+", 1)
{
double doCalc(double d1, double d2) {
return d1+d2;
}
},
SUBTRACT("-",1)
{
double doCalc(double d1, double d2) {
return d1-d2;
}
},
MULTIPLY("*", 2)
{
double doCalc(double d1, double d2) {
return d1*d2;
}
},
DIVIDE("/",2)
{
double doCalc(double d1, double d2) {
return d1/d2;
}
},
STARTBRACE("(", 0)
{
double doCalc(double d1, double d2) {
return 0;
}
},
ENDBRACE(")",0)
{
double doCalc(double d1, double d2) {
return 0;
}
},
EXP("^", 3)
{
double doCalc(double d1, double d2) {
return Math.pow(d1,d2);
}
};
private String operator;
private int precedence;
private Operator(String operator, int precedence) {
this.operator = operator;
this.precedence = precedence;
}
public int getPrecedenceLevel() {
return precedence;
}
public String getSymbol() {
return operator;
}
public static boolean isOperator(String s) {
for(Operator op : Operator.values()) { //iterate through enum values
if (op.getSymbol().equals(s))
return true;
}
return false;
}
public static Operator getOperator(String s)
throws InvalidOperatorException {
for(Operator op : Operator.values()) { //iterate through enum values
if (op.getSymbol().equals(s))
return op;
}
throw new InvalidOperatorException(s + " Is not a valid operator!");
}
public boolean isStartBrace() {
return (operator.equals("("));
}
//overriding calculation provided by each enum part
abstract double doCalc(double d1, double d2);
}
//error to be thrown/caught in ProjectOne.java
class InvalidOperatorException extends Exception {
public InvalidOperatorException() {
}
public InvalidOperatorException(String s) {
super(s);
}
}
//reading in a string at doing the parsing/arithmetic
public static void main (String[] args) {
String input = "";
//get input
System.out.print("Enter an infix exp<b></b>ression: ");
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
try {
input = in.readLine();
}
catch (IOException e)
{
System.out.println("Error getting input!");
}
doCalculate(input);
}
// Input: user entered string
// Output: Display of answer
public static void doCalculate(String equation) {
//our stacks for storage/temp variables
Stack<Operator> operatorStack;
Stack<Double> operandStack;
double valOne, valTwo, newVal;
Operator temp;
//initalize
StringTokenizer tokenizer = new StringTokenizer(equation, " +-*/()^", true);
String token = "";
operandStack = new Stack();
operatorStack = new Stack();
try {
while(tokenizer.hasMoreTokens()){ //run through the string
token = tokenizer.nextToken();
if (token.equals(" ")) { //handles spaces, goes back up top
continue;
}
else if (!Operator.isOperator(token)){ //number check
operandStack.push(Double.parseDouble(token));
}
else if (token.equals("(")) {
operatorStack.push(Operator.getOperator(token));
}
else if (token.equals(")")) { //process until matching paraentheses is found
while (!((temp = operatorStack.pop()).isStartBrace())) {
valTwo = operandStack.pop();
valOne = operandStack.pop();
newVal = temp.doCalc(valOne, valTwo);
operandStack.push(newVal);
}
}
else { //other operators
while (true) { //infinite loop, check for stack empty/top of stack '('/op precedence
if ((operatorStack.empty()) || (operatorStack.peek().isStartBrace()) ||
(operatorStack.peek().getPrecedenceLevel() < Operator.getOperator(token).getPrecedenceLevel())) {
operatorStack.push(Operator.getOperator(token));
break; //exit inner loop
}
temp = operatorStack.pop();
valTwo = operandStack.pop();
valOne = operandStack.pop();
//calculate and push
newVal = temp.doCalc(valOne, valTwo);
operandStack.push(newVal);
}
}
}
}
catch (InvalidOperatorException e) {
System.out.println("Invalid operator found!");
}
//calculate any remaining items (ex. equations with no outer paraentheses)
while(!operatorStack.isEmpty()) {
temp = operatorStack.pop();
valTwo = operandStack.pop();
valOne = operandStack.pop();
newVal = temp.doCalc(valOne, valTwo);
operandStack.push(newVal);
}
//print final answer
System.out.println("Answer is: " + operandStack.pop());
}
//运算符“对象”的枚举
导入java.util.*;
公共枚举运算符{
添加(“+”,1)
{
双doCalc(双d1,双d2){
返回d1+d2;
}
},
减法(“-”,1)
{
双doCalc(双d1,双d2){
返回d1-d2;
}
},
乘(“*”,2)
{
双doCalc(双d1,双d2){
返回d1*d2;
}
},
除(“/”,2)
{
双doCalc(双d1,双d2){
返回d1/d2;
}
},
STARTBRACE(“(”,0)
{
双doCalc(双d1,双d2){
返回0;
}
},
端括号(“)”,0)
{
双doCalc(双d1,双d2){
返回0;
}
},
EXP(“^”,3)
{
双doCalc(双d1,双d2){
返回数学功率(d1,d2);
}
};
私有字符串运算符;
私有整数优先;
专用运算符(字符串运算符,int优先){
this.operator=操作员;
优先权=优先权;
}
public int getPrecenceLevel(){
返回优先级;
}
公共字符串getSymbol(){
返回运算符;
}
公共静态布尔等运算符(字符串s){
对于(运算符op:Operator.values()){//遍历枚举值
if(op.getSymbol().equals))
返回true;
}
返回false;
}
公共静态运算符getOperator(字符串s)
抛出无效操作异常{
对于(运算符op:Operator.values()){//遍历枚举值
if(op.getSymbol().equals))
返回op;
}
抛出新的InvalidOperatorException(s+“不是有效的运算符!”);
}
公共布尔值isStartBrace(){
返回(运算符等于(“”);
}
//覆盖由每个枚举部分提供的计算
双文档摘要(双d1,双d2);
}
//ProjectOne.java中要抛出/捕获的错误
类InvalidOperatorException扩展了异常{
公共无效操作例外(){
}
公共无效操作异常(字符串s){
超级(s);
}
}
//在执行解析/算术时读取字符串
公共静态void main(字符串[]args){
字符串输入=”;
//获取输入
System.out.print(“输入中缀表达式:”);
BufferedReader in=新的BufferedReader(
新的InputStreamReader(System.in));
试试{
input=in.readLine();
}
捕获(IOE异常)
{
System.out.println(“获取输入时出错!”);
}
记录(输入);
}
//输入:用户输入的字符串
//输出:显示答案
公共静态空隙计算(弦方程){
//我们的存储/温度变量堆栈
堆栈运算符堆栈;
堆栈操作数堆栈;
双瓦隆,瓦隆,纽瓦尔;
操作员温度;
//初始化
StringTokenizer tokenizer=新的StringTokenizer(等式“+-*/()^”,true);
字符串标记=”;
操作数堆栈=新堆栈();
运算符堆栈=新堆栈();
试一试{
while(tokenizer.hasMoreTokens()){//遍历字符串
token=tokenizer.nextToken();
如果(token.equals(“”){//处理空格,则返回顶部
继续;
}
如果(!Operator.isOperator(token)){//数字检查
操作数堆栈.push(Double.parseDouble(token));
}
else if(标记为等于(“”){
操作符stack.push(操作符.getOperator(令牌));
}
else if(token.equals(“)”){//处理,直到找到匹配的副焓值
而(!((temp=operatorStack.pop()).isStartBrace()){
valTwo=operandStack.pop();
valOne=operanstack.pop();
newVal=临时文件(valOne,valTwo);
操作数堆栈推送(newVal);
}
}
else{//其他运算符
当(true){//infinite循环时,检查堆栈是否为空/堆栈顶部“(”/op优先级)
if((操作符stack.empty())||(操作符stack.peek().isStartBrace())||
(操作符stack.peek().getPrecenceLevel()2((2+2)+1)
2*((2+2)+1)
public static void doCalculate(String equation) {
// make it explicit:
System.out.println("Got:" + equation);
Pattern pattern = Pattern.compile("([0-9]+|[a-z\\)])(?=[0-9]+|[a-z\\(])");
Matcher m = pattern.matcher(equation);
System.out.println("Made it: "+ (equation = m.replaceAll("$1*")));
//our stacks for storage/temp variables
Stack<Operator> operatorStack;
Stack<Double> operandStack;
double valOne, valTwo, newVal;
Operator temp;