数据结构与算法

计算器

2018-09-01  本文已影响0人  hipeer

使用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;
            }
        }
    }
}
上一篇下一篇

猜你喜欢

热点阅读