java 科学计算+,-,*,/,(,)。字符串分词,语义检查,后缀表达式变换,结果计算

分词

public class ExpressionTokenizer {
    static Pattern pattern = null;
    static String regex = "\\d+(\\.\\d+)?|[+\\-*/()]";

    public ExpressionTokenizer() {
        // 定义一个正则表达式来匹配操作数、运算符和括号
        pattern = Pattern.compile(regex);
    }

    public List<String> tokenize(String expression) {
        Matcher matcher = pattern.matcher(expression);

        List<String> tokens = new ArrayList<>();
        while (matcher.find()) {
            tokens.add(matcher.group());
        }
        return tokens;
    }
}

语义检查,取中缀,后缀表达式转换,计算结果

import java.util.*;

public class ExpressionHandler {

    // 定义运算符的优先级
    private static final Map<String, Integer> PRECEDENCE_MAP = new HashMap<>();

    static {
        PRECEDENCE_MAP.put("+", 1);
        PRECEDENCE_MAP.put("-", 1);
        PRECEDENCE_MAP.put("*", 2);
        PRECEDENCE_MAP.put("/", 2);
    }

    // 语法检查方法
    public boolean validateSyntax(List<String> tokens) {
        Stack<String> operators = new Stack<>();
        Stack<String> operands = new Stack<>();

        for (String token : tokens) {
            if (isNumber(token)) {
                operands.push(token);
            } else if (isOperator(token)) {
                while (!operators.isEmpty() && precedence(operators.peek()) >= precedence(token)) {
                    if (operands.size() < 2) {
                        return false;
                    }
                    operands.pop();
                    operators.pop();
                }
                operators.push(token);
            } else if (token.equals("(")) {
                operators.push(token);
            } else if (token.equals(")")) {
                while (!operators.isEmpty() && !operators.peek().equals("(")) {
                    if (operands.size() < 2) {
                        return false;
                    }
                    operands.pop();
                    operators.pop();
                }
                if (operators.isEmpty() || !operators.peek().equals("(")) {
                    return false;
                }
                operators.pop(); // Pop the '(' from stack
            } else {
                return false; // Invalid token
            }
        }

        while (!operators.isEmpty()) {
            if (operands.size() < 2) {
                return false;
            }
            operands.pop();
            operators.pop();
        }

        return operands.size() == 1;
    }


    // 检查是否是数字
    private boolean isNumber(String token) {
        return token.matches("\\d+(\\.\\d+)?");
    }

    // 检查是否是运算符
    private boolean isOperator(String token) {
        return PRECEDENCE_MAP.containsKey(token);
    }

    // 获取运算符优先级
    private int precedence(String operator) {
        return PRECEDENCE_MAP.getOrDefault(operator, -1);
    }

    // 将分词列表转为中缀表达式字符串
    public String tokensToInfix(List<String> tokens) {
        StringBuilder infix = new StringBuilder();
        for (String token : tokens) {
            infix.append(token).append(" ");
        }
        return infix.toString().trim();
    }

    // 将中缀表达式转换为后缀表达式
    public List<String> infixToPostfix(List<String> tokens) {
        Stack<String> operators = new Stack<>();
        List<String> postfix = new ArrayList<>();

        for (String token : tokens) {
            if (isNumber(token)) {
                postfix.add(token);
            } else if (isOperator(token)) {
                while (!operators.isEmpty() && precedence(operators.peek()) >= precedence(token)) {
                    postfix.add(operators.pop());
                }
                operators.push(token);
            } else if (token.equals("(")) {
                operators.push(token);
            } else if (token.equals(")")) {
                while (!operators.isEmpty() && !operators.peek().equals("(")) {
                    postfix.add(operators.pop());
                }
                if (!operators.isEmpty() && operators.peek().equals("(")) {
                    operators.pop();
                }
            }
        }

        while (!operators.isEmpty()) {
            postfix.add(operators.pop());
        }

        return postfix;
    }

    // 计算后缀表达式的值
    public double evaluatePostfix(List<String> tokens) {
        Stack<Double> stack = new Stack<>();

        for (String token : tokens) {
            if (isNumber(token)) {
                stack.push(Double.parseDouble(token));
            } else if (isOperator(token)) {
                double b = stack.pop();
                double a = stack.pop();
                switch (token) {
                    case "+":
                        stack.push(a + b);
                        break;
                    case "-":
                        stack.push(a - b);
                        break;
                    case "*":
                        stack.push(a * b);
                        break;
                    case "/":
                        stack.push(a / b);
                        break;
                }
            }
        }

        return stack.pop();
    }

}

验证

public static void main(String[] args) {
        String expression = "3.5 + 4 * (2 - 1.5) / 2";
        ExpressionTokenizer expressionTokenizer = new ExpressionTokenizer();
        List<String> tokens = expressionTokenizer.tokenize(expression);
        ExpressionHandler expressionHandler = new ExpressionHandler();
        if (expressionHandler.validateSyntax(tokens)) {
            System.out.println("The expression is syntactically correct.");
        } else {
            System.out.println("The expression is syntactically incorrect.");
        }
        System.out.println(expressionHandler.tokensToInfix(tokens));

        List<String> postfixTokens = expressionHandler.infixToPostfix(tokens);
        System.out.println("Postfix tokens: " + postfixTokens);

        double v = expressionHandler.evaluatePostfix(postfixTokens);
        System.out.println("result=" + v);

    }

  • 9
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值