组合模式实现简单计算器功能

#组合模式实现简单计算器功能

顶层接口

public interface Expression {
    int getValue();
}

存储左右表达式的抽象类

public abstract class BinaryOperatorExpression implements Expression {
    Expression left;
    Expression right;

    protected BinaryOperatorExpression(Expression left, Expression right) {
        this.left = left;
        this.right = right;
    }
}

加减乘除实现类

public class AddExpression extends BinaryOperatorExpression {
    public AddExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    public int getValue() {
        return left.getValue() + right.getValue();
    }
}
public class SubtractExpression extends BinaryOperatorExpression {
    public SubtractExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    public int getValue() {
        return left.getValue() - right.getValue();
    }
}
public class MultiplyExpression extends BinaryOperatorExpression {
    public MultiplyExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    public int getValue() {
        return left.getValue() * right.getValue();
    }
}
public class DivisionExpression extends BinaryOperatorExpression {
    public DivisionExpression(Expression left, Expression right) {
        super(left, right);
    }

    @Override
    public int getValue() {
        return left.getValue() / right.getValue();
    }
}

顶层接口实现类

public class NumberExpression implements Expression {
    private final int value;

    public NumberExpression(int value) {
        this.value = value;
    }

    @Override
    public int getValue() {
        return this.value;

    }
}

测试类

public class ExpressionParse {
    private static final Set<String> OPERATOR = Set.of("+", "-", "*", "/");

    public static void main(String[] args) throws IllegalAccessException {
        System.out.println(parse("12 + (2 * 3)").getValue());
    }

    /**
     * 将前缀表达式转换为后缀表达式
     *
     * @param prefixExpression 前缀表达式
     * @return 后缀表达式
     * @throws IllegalAccessException 非法字符
     */
    public static List<String> toSuffixExpression(String prefixExpression) throws IllegalAccessException {
        // 后缀表达式
        List<String> suffixExpression = new ArrayList<>();
        // 辅助栈
        Stack<String> symbolStack = new Stack<>();
        int point = 0;
        while (point < prefixExpression.length()) {
            char c = prefixExpression.charAt(point);
            switch (c) {
                case ' ':
                    break;
                case '(':
                    symbolStack.push(String.valueOf(c));
                    break;
                case ')':
                    while (!"(".equals(symbolStack.peek())) {
                        suffixExpression.add(symbolStack.pop());
                    }
                    symbolStack.pop();
                    break;
                case '*':
                case '/':
                    while (!symbolStack.isEmpty() && ("*".equals(symbolStack.peek()) || "/".equals(symbolStack.peek()))) {
                        suffixExpression.add(symbolStack.pop());
                    }
                    symbolStack.push(String.valueOf(c));
                    break;
                case '+':
                case '-':
                    while (topIsOperator(symbolStack)) {
                        suffixExpression.add(symbolStack.pop());
                    }
                    symbolStack.push(String.valueOf(c));
                    break;
                default:
                    if (Character.isDigit(c)) {
                        StringBuilder stringBuilder = new StringBuilder();
                        while (point < prefixExpression.length() && Character.isDigit(prefixExpression.charAt(point))) {
                            stringBuilder.append(prefixExpression.charAt(point));
                            point++;
                        }
                        point--;
                        suffixExpression.add(stringBuilder.toString());
                    } else {
                        throw new IllegalAccessException("非法字符!");
                    }
                    break;
            }
            point++;
        }

        while (!symbolStack.isEmpty()) {
            suffixExpression.add(symbolStack.pop());
        }
        return suffixExpression;
    }

    /**
     * 判断栈顶是否为操作符
     *
     * @param symbolStack 栈
     * @return
     */
    private static boolean topIsOperator(Stack<String> symbolStack) {
        return !symbolStack.isEmpty() && OPERATOR.contains(symbolStack.peek());
    }

    /**
     * 计算结果
     *
     * @param prefixExpression 前缀表达式
     * @return 结果
     * @throws IllegalAccessException 非法字符
     */
    public static Expression parse(String prefixExpression) throws IllegalAccessException {
        List<String> suffixExpression = toSuffixExpression(prefixExpression);
        Stack<Expression> stack = new Stack<>();
        for (String item : suffixExpression) {
            switch (item) {
                case "+":
                    Expression rightAdd = stack.pop();
                    stack.push(new AddExpression(stack.pop(), rightAdd));
                    break;
                case "-":
                    Expression rightSubtract = stack.pop();
                    stack.push(new SubtractExpression(stack.pop(), rightSubtract));
                    break;
                case "*":
                    Expression rightMultiply = stack.pop();
                    stack.push(new MultiplyExpression(stack.pop(), rightMultiply));
                    break;
                case "/":
                    Expression rightDivision = stack.pop();
                    stack.push(new DivisionExpression(stack.pop(), rightDivision));
                    break;
                default:
                    int value = Integer.parseInt(item);
                    stack.push(new NumberExpression(value));
                    break;
            }
        }
        return stack.pop();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值