计算器

作者: hipeer | 来源:发表于2018-09-01 17:32 被阅读0次

    使用Java写的一个可以计算+,-,*,/ 的计算器。首先用栈把中缀表达式转化成后缀表达式,再利用栈对后缀表达式求值。大致思路就是这样代码看下面

    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;
    import java.util.Stack;
    
    /**
     * 思路:首先把中缀表达式转成 后缀表达式 利用后缀表达式求值
     * 
     *
     */
    public class Calputer {
    
        // 把中缀表达式转换为后缀表达式
        public String translateStr(String str) {
            StringBuffer buffer = new StringBuffer();
            int len = str.length();
            Character topChar;
            Stack<Character> stack = new Stack<Character>();
            int count = 0;                                      // 数字位数计数器, 用来区别是多位数字还是一位数字
            for (int i = 0; i < len; i++) {
                boolean flag = false;                           // 运算符出栈时使用,作为循环条件使用, 栈顶元素优先级小于nextChar的标志
                Character nextChar = str.charAt(i);
                if (isDigit(nextChar)) {
                    if (count == 0) {                           // 每个数字在输出时在前面添加一个空格
                        buffer.append(" ");
                    }
                    buffer.append(nextChar);
                    count++;
                } else {
                    switch (nextChar) {
                    case '+':
                    case '-':
                    case '*':
                    case '/':
                        while (!flag && !stack.empty()) {       // 循环比较nextChar和topChar的优先级
                            topChar = stack.peek();             // 先取出栈顶元素
                            if (getPre(nextChar) <= getPre(topChar)) { // 比较优先级, 如果栈顶元素的优先级大于nextChar就出栈
                                buffer.append(" ");
                                buffer.append(topChar);         // 把栈顶元素添加到字符串
                                stack.pop();                    // 出栈
                            } else {                            // 如果栈顶元素优先级小于nextChar的优先级,就结束while循环,则nextChar进栈
                                flag = true;                    // 把flag设为true,结束循环
                            }
                        } // end while()
                        stack.push(nextChar);                   // 进栈
                        break;
    
                    case '(':                                   // 遇到'('直接进栈
                        stack.push(nextChar);
                        break;
    
                    case ')':                                   // 遇到')' 就要循环出栈, 直到遇到'('时结束循环
                        topChar = stack.pop();                  // 首先弹出栈顶的元素
                        while (topChar != '(') {                // 开始循环出栈直到遇到'('结束
                            buffer.append(" ");
                            buffer.append(topChar);
                            topChar = stack.pop();              // 出栈
                        }
                        break;
    
                    default:
                        break;
                    } // end switch()
                    count = 0;                                  // else语句块执行完毕把计数器归零
                } // end else
            } // end for()
            while (!stack.empty()) {
                topChar = stack.pop();
                buffer.append(" ");
                buffer.append(topChar);
            } // end while()
            return buffer.toString();
        }
    
        // 获取运算符优先级
        public int getPre(Character c) {
            switch (c) {
            case '(':
            case ')':
                return 0;
            case '+':
            case '-':
                return 1;
            case '*':
            case '/':
                return 2;
            }
            return -1;
        }
    
        // 输入检查
        public boolean checkStr(String str) {
            for (int i = 0; i < str.length(); i++) {
                if (Character.isLetter(str.charAt(i))) {
                    return false;
                }
            }
            return true;
        }
    
        // 是否为数字
        public boolean isDigit(char str) {
            return Character.isDigit(str);
        }
    
        // 处理后缀表达式,并计算结果
        public int Solution(String str1) {
            Stack<Character> stack = new Stack<Character>();
            String str = translateStr(str1);
            // System.out.println(str);
            String[] arr = str.split(" ");
            // arr里面存在一些空字符串,所以用了个list集合过滤一下
            List<String> list = new ArrayList<String>();
            for (String s : arr) {
                if (!s.equals("")) {
                    list.add(s);
                }
            }
    
            int result = 0;
            Character nextChar;
            for (String s : list) {                                 // 遍历集合, 计算后缀表达式
                if (isDigit(s.charAt(0))) {                         // 根据集合中元素的首字符来判断是数字还是运算符
                    nextChar = (char) ((int)Integer.valueOf(s));    // 需要把字符串类型的数字转成char类型压入栈
                    stack.push(nextChar);                           // 让数字进栈
                } else {                                            // 如果是运算符
                    nextChar = s.charAt(0);
                    int right = (int) (stack.pop());                // 从栈中弹出两个数字
                    int left = (int) (stack.pop());
                    int res = getResult(right, left, nextChar);     // 对弹出的数字进行运算, 运算符为nextChar
                    Character newChar = (char) (res);               // 把结果转为char再进栈
                    stack.push(newChar);
                }
            }
            result = (int) (stack.pop());                           // list遍历结束, 此时栈中只有一个元素, 就是计算结果, 出栈
            return result;
        }
    
        // 计算两个数字的运算结果
        private int getResult(int rightNum, int leftNum, Character nextChar) {
            int result = 0;
            switch (nextChar) {
            case '+':
                result = leftNum + rightNum;
                break;
            case '-':
                result = leftNum - rightNum;
                break;
            case '*':
                result = leftNum * rightNum;
                break;
            case '/':
                result = leftNum / rightNum;
                break;
            default:
                break;
            }
            return result;
        }
    
        public static void main(String[] args) {
            Calputer calputer = new Calputer();
            Scanner scan = new Scanner(System.in);
            while (true) {
                System.out.print("In: ");
                str = scan.nextLine();
                if (!calputer.checkStr(str)) {
                    System.out.println("Connot include English character.");
                    continue;
                }
                try {
                    int res = calputer.Solution(str);
                    System.out.println("Out: " + res);
                } catch (Exception e) {
                    System.out.println("FormatError.");
                    continue;
                }
            }
        }
    }
    

    相关文章

      网友评论

        本文标题:计算器

        本文链接:https://www.haomeiwen.com/subject/cmyuwftx.html