表达式计算(java实现)

表达式计算(java实现)

蓝桥杯: 算法训练 表达式计算

问题描述
  输入一个只包含加减乖除和括号的合法表达式,求表达式的值。其中除表示整除。
输入格式
  输入一行,包含一个表达式。
输出格式
  输出这个表达式的值。
样例输入
1-2+3*(4-5)
样例输出
-4
数据规模和约定
  表达式长度不超过100,表达式运算合法且运算过程都在int内进行。

import java.util.Scanner;

class characterNum {
    int length;
    int[] num;// 用来存数字
    char[] fuhao;// 用来存符号
    boolean[] isEmpty;// 判断是否为空
    // 三串各类型数组
    //例:9+44*(8-2/1)
    //  num:[9, ,44, , , ,8, ,2, ,1, ]
    //fuhao:[ ,+,  , ,*,(, ,-, ,/, ,)]
    //isEmpty:[false,false,false,true,false,false,false,false,false,false,false]

    /**
    *构造初始化
    */
    public characterNum(int N) {
        length = N;
        num = new int[N];
        fuhao = new char[N];
        isEmpty = new boolean[N];
    }

    // 格式化整个String,数字存num里,符号存符号里,中间数字里留的的空设isEmpty=true
    void structured(String getin) {
        for (int i = 0; i < length; i++) {
            if (getin.charAt(i) == '+') {
                fuhao[i] = '+';
                isEmpty[i] = false;
            } else if (getin.charAt(i) == '-') {
                fuhao[i] = '-';
                isEmpty[i] = false;
            } else if (getin.charAt(i) == '*') {
                fuhao[i] = '*';
                isEmpty[i] = false;
            } else if (getin.charAt(i) == '/') {
                fuhao[i] = '/';
                isEmpty[i] = false;
            } else if (getin.charAt(i) == '(') {
                fuhao[i] = '(';
                isEmpty[i] = false;
            } else if (getin.charAt(i) == ')') {
                fuhao[i] = ')';
                isEmpty[i] = false;
            } else if (getin.charAt(i) == '#') {
                isEmpty[i] = true;
            } else {
                for (int j = i; j < length; j++) {
                    if (getin.charAt(j) < '0' || getin.charAt(j) > '9') {
                        // 循环处理连续的char型数字转为一个int数字
                        for (int temp = i, cout = 1; temp != j; temp++, cout++) {
                            num[i] += ((int) getin.charAt(temp) - 48) * (int) (Math.pow(10, j - i - cout));
                        }
                        i = j - 1;// 返回是符号的前一个值给i,方便下次循环i++个存为符号
                        break;
                    } else {
                        if (i == j) {
                            isEmpty[i] = false;// 标记第一个i的时候不为空
                        }
                        if (j != i) {
                            isEmpty[j] = true;// 后续的都标记为空
                        }
                    }
                }
            }
        }
        /*
         * for (int c : num) { System.out.print(c + " "); }
         */
    }

    // 遍历寻找一对括号,计算括号内的值
    public void calculate() {
        boolean loop = true;
        while (loop) {
            int left = 0, right = 0;
            for (int i = 0; i < length; i++) {
                if (!isEmpty[i] && fuhao[i] == '(') {
                    left = i;
                } else if (!isEmpty[i] && fuhao[i] == ')') {
                    right = i;
                    break;
                }
            }
            // 没有括号了,直接遍历计算
            if (left == 0 && right == 0) {
                calculate_third(0, length - 1);
                loop = false;// 结束循环
            } else {
                calculate_second(left, right);//还有括号的情况
            }
        }
    }

    // 计算括号内的值,赋给左括号右边的空,后边直到右括号,全部赋为isEmpty=true
    private void calculate_second(int left, int right) {
        calculate_third(left + 1, right - 1);
        isEmpty[left] = true;
        isEmpty[right] = true;
    }

    // 直接计算
    private void calculate_third(int m, int n) {
        int num1 = 0;// 符号左边的数字
        int no1 = 0;
        int num2 = 0;// 符号右边的数字
        int no2 = 0;
        for (int i = m; i <= n; i++)// 遍历算完所有乘除法
        {
            if (!isEmpty[i] && (fuhao[i] == '*' || fuhao[i] == '/')) {
                for (int temp1 = m; temp1 < i; temp1++) {
                    if (!isEmpty[temp1] 
                        && fuhao[temp1] != '+' 
                        && fuhao[temp1] != '-' 
                        && fuhao[temp1] != '*'
                        && fuhao[temp1] != '/')// 找到乘号或除号左边的数
                        {
                            num1 = num[temp1];
                            no1 = temp1;
                        }
                }
                for (int temp2 = i + 1; temp2 <= n; temp2++) {
                    if (!isEmpty[temp2] 
                        && fuhao[temp2] != '+' 
                        && fuhao[temp2] != '-' 
                        && fuhao[temp2] != '*'
                        && fuhao[temp2] != '/')// 找到符号右边第一个数
                        {
                            num2 = num[temp2];
                            no2 = temp2;
                            break;// 只要找到一个
                        }
                }
                if (fuhao[i] == '*') {
                    num[no1] = num1 * num2;
                } else if (fuhao[i] == '/') {
                    num[no1] = num1 / num2;
                }
                DeletToTure(no1 + 1, no2);
            }
        }


        for (int i = m; i <= n; i++)// 遍历算完所有加减法
        {
            if (!isEmpty[i] && (fuhao[i] == '+' || fuhao[i] == '-')) {
                for (int temp1 = m; temp1 < i; temp1++) {
                    if (!isEmpty[temp1] 
                        && fuhao[temp1] != '+' 
                        && fuhao[temp1] != '-' 
                        && fuhao[temp1] != '*'
                        && fuhao[temp1] != '/') 
                        {
                            num1 = num[temp1];
                            no1 = temp1;
                        }
                }
                for (int temp2 = i + 1; temp2 <= n; temp2++) {
                    if (!isEmpty[temp2] 
                        && fuhao[temp2] != '+' 
                        && fuhao[temp2] != '-' 
                        && fuhao[temp2] != '*'
                        && fuhao[temp2] != '/') 
                        {
                            num2 = num[temp2];
                            no2 = temp2;
                            break;
                        }
                }
                if (fuhao[i] == '+') {
                    num[no1] = num1 + num2;
                } else if (fuhao[i] == '-') {
                    num[no1] = num1 - num2;
                }
                DeletToTure(no1 + 1, no2);
            }
        }

    }

    private void DeletToTure(int i, int j) {
        for (; i <= j; i++) {
            isEmpty[i] = true;
        }
    }

    public void sysout() {
        for (int i = 0; i < length; i++) {
            if (!isEmpty[i]) {
                System.out.println(num[i]);
            }
        }
    }

}

public class BiaoDaShiJiSuan {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String getin = sc.nextLine();
        getin = getin + "#";// 结束标记
        // 初始化
        characterNum n = new characterNum(getin.length());
        // 结构化
        n.structured(getin);
        // 计算
        n.calculate();
        // 输出
        n.sysout();

        sc.close();

    }

}

没有采用栈结构,将中序转为后序的算法
而是自己用了三个数组,依次存储数字,符号,标记(是否为空)
例:9+44*(8-2/1)
num:[9, ,44, , , ,8, ,2, ,1, ]
fuhao:[ ,+, , ,*,(, ,-, ,/, ,)]
isEmpty:[false,false,false,true,false,false,false,false,false,false,false]

总长度为字符串长度
1.第一步将字符串结构化成三个数组
2.第二步遍历符号数组,寻找一对括号
3.计算括号内的值,赋给左括号右边的位置,左右括号标记为空,括号内除第一个位置外也标记为空
num:[9, ,44, , , ,6, ,2, ,1, ]
fuhao:[ ,+, , ,*,(, ,-, ,/, ,)]
isEmpty:[false,false,false,true,false,true,false,true,true,true,true]
4. 继续遍历,直到没有括号,就直接计算

结果

9+44*(8-2/1)
273

第一次用markdown编辑器。。。。

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值