`

中序后缀表达式

    博客分类:
  • Java
 
阅读更多
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Stack;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

//测试用例:1-3*(4-(2+5*3)+5)-6/(1+2)=23
//测试用例:11.2+3.1*(423-(2+5.7*3.4)+5.6)-6.4/(15.5+24)=1273.4199746835445
public class MyCalculate {

    private Pattern pattern;
    private Matcher matcher;

    public static void main(String[] args) throws IOException {
        String str_input;
        while (true) {
            System.out.print("输入表达式: ");
            System.out.flush();

            str_input = getString();
            if (str_input.equals("")) {
                break;
            }

            MyCalculate calculator = new MyCalculate();
            calculator.calculate(str_input);
        }

    }

    public void calculate(String str_input) {
        try {
            double result;

            // 以下对输入字符串做规则处理
            str_input = checkExpression(str_input);

            // 以下对输入字符串做表达式转换
            Vector<String> computeVector = getExpression(str_input);

            // for (int i=0;i<v_compute.size();i++ ) 
			    { System.out.print("  "+v_compute.get(i)); }

            // 以下进行后缀表达式转换
            Vector<String> suffixVector = transformToSuffix(computeVector);

            // for (int i=0;i<v_tmp_prefix.size();i++ ) 
			    { System.out.print(v_tmp_prefix.get(i)); }

            // 以下进行后缀表达式运算
            result = evaluateSuffix(suffixVector);

            System.out.println("结果 = " + result);
        } catch (RuntimeException e) {
            System.out.println(e.getMessage() == null ? "表达式出错" : e.getMessage());
        }
    }

    /** 表达式正确性规则处理与校验 */
    public String checkExpression(String str) {
        Stack<Character> checkBrackets = new Stack<Character>();
        Stack<Character> tmpStack = new Stack<Character>();
        String result = "";

        // 匹配合法的运算字符"数字,.,+,-,*,/,(,),"
        String calculateStr = "^[\\.\\d\\+\\-\\*/\\(\\)]+$";
        pattern = Pattern.compile(calculateStr);
        matcher = pattern.matcher(str);
        boolean isFindErrStr = matcher.matches();
        if (!isFindErrStr) {
            throw new RuntimeException("出现非运算字符");
        }

        // 匹配非法的浮点数.
        String errFloatStr = ".*(\\.\\d*){2,}.*";
        pattern = Pattern.compile(errFloatStr);
        matcher = pattern.matcher(str);
        boolean isErrFloat = matcher.matches();
        if (isErrFloat) {
            throw new RuntimeException("非法的浮点数");
        }

        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            if (checkFig(ch)) { // 数字
                if (!tmpStack.isEmpty() && tmpStack.peek() == ')') {
                    throw new RuntimeException("以')'开头的表达式");
                }
                tmpStack.push(ch);
                result = result + ch;
            } else { // 符号
                switch (ch) {
                case '(':
                    if (!tmpStack.isEmpty() && (tmpStack.peek() == '.')) {
                        throw new RuntimeException("'('前不能使'.'");
                    }
                    checkBrackets.push(ch);
                    if (tmpStack.isEmpty()
                            || (!checkFig(tmpStack.peek()) && tmpStack.peek() != ')')) {
                        result = result + ch;
                    } else {
                        result = result + "*" + ch;
                    }
                    tmpStack.push(ch);
                    break;
                case ')':
                    if (!checkBrackets.isEmpty()) {
                        char chx = checkBrackets.pop();
                        if (chx != '(') {
                            throw new RuntimeException("括号出现不配对");
                        }
                    } else {
                        throw new RuntimeException("括号出现不配对");
                    }
                    if (tmpStack.peek() == '.'
                            || (!checkFig(tmpStack.peek()) && tmpStack.peek() != ')')) {
                        throw new RuntimeException("')'出现位置错误");
                    }
                    tmpStack.push(ch);
                    result = result + ch;
                    break;
                case '+':
                case '-':
                    if (!tmpStack.isEmpty()
                            && (tmpStack.peek() == '+' || tmpStack.peek() == '-'
                                    || tmpStack.peek() == '*' || tmpStack.peek() == '/' 
									|| tmpStack.peek() == '.')) {
                        throw new RuntimeException("连续出现运算字符");
                    }
                    if (tmpStack.isEmpty() || tmpStack.peek() == '(') {
                        result = result + "0" + ch;
                    } else {
                        result = result + ch;
                    }
                    tmpStack.push(ch);
                    break;
                case '*':
                case '/':
                    if (tmpStack.isEmpty()) {
                        throw new RuntimeException("以乘号除号开头");
                    }
                    if ((!checkFig(tmpStack.peek()) && tmpStack.peek() != ')')) {
                        throw new RuntimeException("连续出现运算字符");
                    }
                    tmpStack.push(ch);
                    result = result + ch;
                    break;
                case '.':
                    if (tmpStack.isEmpty() || !checkFig(tmpStack.peek())) {
                        result = result + "0" + ch;
                    } else {
                        result = result + ch;
                    }
                    tmpStack.push(ch);
                    break;

                default:
                    break;
                }
            }
        }
        if (!checkBrackets.isEmpty()) {
            throw new RuntimeException("括号出现不配对");
        }

        return result;
    }

    /** 输入字符串转换.把从控制台读入的字符串转成表达式存在一个队列中.
        例:123+321 存为"123""+""321" */
    public Vector<String> getExpression(String str) {
        Vector<String> tmpVctr = new Vector<String>();
        char[] temp = new char[str.length()];
        str.getChars(0, str.length(), temp, 0);
        String fi = "";
        int i = 0;
        // 匹配数字和小数点
        String regex_fig = "[\\.\\d]";
        // 匹配运算符(+,-,*,/)和括号("(",")")
        String regex_operator = "[\\+\\-\\*/\\(\\)]";
        Pattern numPtn = Pattern.compile(regex_fig);
        Pattern operatorPtn = Pattern.compile(regex_operator);
        Matcher m = null;
        boolean b;
        while (i < str.length()) {
            Character c = new Character(temp[i]);
            String s = c.toString();
            m = operatorPtn.matcher(s);
            b = m.matches();

            if (b) {
                tmpVctr.add(fi);
                fi = "";
                tmpVctr.add(s);
            }
            m = numPtn.matcher(s);
            b = m.matches();
            if (b) {
                fi = fi + s;
            }
            i++;
        }
        tmpVctr.add(fi);

        return tmpVctr;
    }

    /** 转换中序表示式为后缀表示式 */
    public Vector<String> transformToSuffix(Vector<String> expressionVctr) {
        Vector<String> suffixVctr = new Vector<String>();
        Stack<String> tmpStack = new Stack<String>();
        // 匹配正浮点数
        String regexFloat = "\\d+(\\.\\d+)?";
        pattern = Pattern.compile(regexFloat);
        boolean b;
        String str = "";

        for (int i = 0; i < expressionVctr.size(); i++) {
            str = expressionVctr.get(i).toString();
            matcher = pattern.matcher(str);
            b = matcher.matches();

            if (b) {
                suffixVctr.add(str);
            } else {
                if (str.equals("+") || str.equals("-")) {
                    if (tmpStack.isEmpty()) {
                        tmpStack.push(str);
                    } else {
                        while (!tmpStack.isEmpty()) {
                            String tmpStr = tmpStack.peek();

                            if (tmpStr.equals("(")) {
                                break;
                            } else {
                                suffixVctr.add(tmpStack.pop());
                            }
                        }
                        tmpStack.push(str);
                    }
                }

                if (str.equals("*") || str.equals("/")) {
                    if (tmpStack.isEmpty()) {
                        tmpStack.push(str);
                    } else {
                        while (!tmpStack.isEmpty()) {
                            String tmpStr = tmpStack.peek();

                            if (tmpStr.equals("(") || tmpStr.equals("+") 
                                || tmpStr.equals("-")) {
                                break;
                            } else {
                                suffixVctr.add(tmpStack.pop());
                            }
                        }
                        tmpStack.push(str);
                    }
                }

                if (str.equals("(")) {
                    tmpStack.push(str);
                }

                if (str.equals(")")) {
                    while (!tmpStack.isEmpty()) {
                        String tmpStr = tmpStack.peek();
                        if (tmpStr.equals("(")) {
                            tmpStack.pop();
                            break;
                        } else {
                            suffixVctr.add(tmpStack.pop());
                        }
                    }
                }
            }
        }
        while (!tmpStack.isEmpty()) {
            suffixVctr.add(tmpStack.pop());
        }
        return suffixVctr;
    }

    /** 后缀表示式求值 */
    public strictfp double evaluateSuffix(Vector<String> suffixVctr) {
        String tmpStr = "";
        double num1, num2, interAns = 0;
        Stack<Double> computeStack = new Stack<Double>();

        int i = 0;
        while (i < suffixVctr.size()) {
            tmpStr = suffixVctr.get(i).toString();
            if (!tmpStr.equals("+") && !tmpStr.equals("-") && !tmpStr.equals("*")
                    && !tmpStr.equals("/")) {
                interAns = computeStack.push(Double.parseDouble(tmpStr));
            } else {
                num2 = (Double) (computeStack.pop());
                num1 = (Double) (computeStack.pop());

                if (tmpStr.equals("+")) {
                    interAns = num1 + num2;
                }
                if (tmpStr.equals("-")) {
                    interAns = num1 - num2;
                }
                if (tmpStr.equals("*")) {
                    interAns = num1 * num2;
                }
                if (tmpStr.equals("/")) {
                    interAns = num1 / num2;
                }
                computeStack.push(interAns);
            }
            i++;
        }
        return interAns;
    }

    /** 括号匹配检测 */
    public boolean checkBracket(String str) {
        Stack<Character> s_check = new Stack<Character>();
        boolean b_flag = true;

        for (int i = 0; i < str.length(); i++) {
            char ch = str.charAt(i);
            switch (ch) {
            case '(':
                s_check.push(ch);
                break;
            case ')':
                if (!s_check.isEmpty()) {
                    char chx = s_check.pop();
                    if (ch == ')' && chx != '(') {
                        b_flag = false;
                    }
                } else {
                    b_flag = false;
                }
                break;
            default:
                break;
            }
        }
        if (!s_check.isEmpty()) {
            b_flag = false;
        }
        return b_flag;
    }

    /** 是否是一位数字 */
    private boolean checkFig(Object ch) {
        String s = ch.toString();
        // 匹配数字
        String regexNum = "\\d";
        pattern = Pattern.compile(regexNum);
        matcher = pattern.matcher(s);
        boolean b_fig = matcher.matches();
        return b_fig;
    }

    /**
     *静态方法,用来从控制台读入表达式
     */
    public static String getString() throws IOException {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        String s = br.readLine();
        return s;
    }
}

分享到:
评论

相关推荐

    中序表达式计算(四则混合).zip_中序表达式_表达式计算

    在编程领域,中序表达式计算...总结起来,中序表达式计算涉及了数据结构(栈)、算法(中序转后序、后缀表达式计算)以及四则混合运算的规则。通过理解这些知识点,我们可以编写出能正确处理各种中序表达式的计算程序。

    中缀表达式转后缀表达式程序C语言版

    这里我们关注的是将中缀表达式转换为后缀表达式,也称为逆波兰表示法。中缀表达式是我们通常使用的算术表达式形式,如 `2 + 3 * 4`,其中运算符位于其操作数之间。而后缀表达式则将运算符置于操作数之后,如 `2 3 4 ...

    C++前中后缀表达式转表达式二叉树

    选择输入前中后缀表达式,建立表达式二叉树,再前序中序后序遍历二叉树,输出三种形式的表达式

    中缀后缀表达式变表达式二叉树并且三种顺序历遍.zip

    本话题主要涉及如何将中缀表达式转化为后缀表达式,以及如何构建表达式二叉树,并介绍三种二叉树遍历方法:前序遍历、中序遍历和后序遍历。 首先,中缀表达式是我们日常生活中常见的数学表达式形式,如2 + 3 * 4。...

    后缀逆波兰式代码

    后缀逆波兰式计算的设计思路是将中序表达式转换为后缀逆波兰式,然后使用栈和队列实现后缀逆波兰式的计算。这种设计思路可以解决中序表达式的计算问题,并且可以提高计算效率。 二、实现方法 后缀逆波兰式计算的...

    中序表达式转前序后序

    3. **后序遍历**:按照“左-右-根”的顺序访问节点,后序遍历常用于构造后缀表达式,也称为逆波兰表示法,如`2 3 +`。 中序表达式转前序表达式和后序表达式的步骤如下: **中序转前序**: 1. 创建一个空栈,用于...

    用C语言写出的关于中序表达式求值的源代码

    - `InToPost` 函数是核心算法,它遍历输入的中序表达式,根据操作符和操作数的规则将中序表达式转换为后缀表达式,并计算表达式的值。在处理过程中,遇到操作符时会比较其优先级,如果当前操作符的优先级高于堆栈...

    前缀表达式转换和表达式计算设计报告

    前序遍历(PreOrder Traversal)对应于前缀表达式,中序遍历(InOrder Traversal)对应于中缀表达式,后序遍历(PostOrder Traversal)对应于后缀表达式。遍历时,先输出当前节点的值(对于运算符,它会出现在表达式...

    表达式二叉树

    程序根据后缀表达式建立二叉树,建立过程中用到了栈,并分别采取递归和非递归的方法,对二叉树进行了先序、中序、后续遍历。

    表达式的值

    为了进行求值,我们需要将其转换成其他形式,如前缀表达式(Prefix)或后缀表达式(Postfix),也称为逆波兰表示法(Reverse Polish Notation, RPN)。 在C++中,中序表达式求值通常通过使用栈(Stack)数据结构来...

    c++实现字符串表达式求值(逆波兰式)

    在程序设计中,可能碰到需要对字符串数学表达式求值...后缀表达式也称逆波兰表达式 因其使表达式求值变得轻松,所以被普遍使用。 程序解析字符串表达式,将其转换为逆波兰式,然后生成表达式二叉树,最后计算表达式值。

    湖南大学数据结构实验4四则运算表达式求值实验报告

    本次实验的主要目标是实现一个程序,能够处理用户输入的整数四则运算表达式(中缀表达式),将其转换为后缀表达式,并计算后缀表达式的值。具体的需求如下: 1. **程序基本功能** - 用户输入一个包含加减乘除四则...

    c语言 实现二叉树操作 用栈实现算术表达式求值

    - 从左到右扫描后缀表达式,遇到数字时压入栈,遇到运算符时弹出栈顶的两个操作数进行运算,结果再压回栈。 - 最后栈中仅剩的一个数值就是表达式的值。 在设计过程中,需要实现以下函数: - `CreateBiTree`:根据...

    纯汇编写的中序算式计算器(原创+中文注释+带测试用例)

    在解析这种表达式时,通常采用后缀表达式(逆波兰表示法)或中缀表达式的转换来简化计算。 2. **计算器实现**:本计算器的实现采用了中序遍历的方法,这是对树结构进行遍历的一种常见策略。在中序遍历中,我们首先...

    表达式计算

    这些表达式可以通过不同的数据结构来表示,比如操作符优先级表、后缀表达式(逆波兰表示法)或者表达式树。 表达式树是一种直观的方式来表示表达式,其中每个节点代表一个操作符或操作数,左子树代表操作符的左操作...

    数据结构(c语言)单链表 表达式求值 二叉树 二叉排序树 Huffman编码

    在这个项目中,可能实现了一个简单的解析器,它可以读取用户输入的中缀表达式,将其转换为后缀表达式(也称为逆波兰表示法),然后使用栈来评估这个表达式。这种方法避免了优先级和括号的问题,因为运算符总是位于其...

    以二叉树结构存储算术表达式并计算结果

    2. **前缀、中缀和后缀表达式**:算术表达式在二叉树中的表示通常与前缀(逆波兰)、中缀(常规)和后缀(波兰)表达式有关。前缀表达式将运算符放在操作数前面,后缀表达式将运算符放在操作数后面,而中缀表达式是...

    数据结构 课程设计.doc

    在这个课程设计中,主要关注了两个关键主题:后缀表达式的计算和二叉树的遍历。 后缀表达式(也称为逆波兰表达式)是一种数学表达式表示方式,它避免了括号的使用,通过将运算符放在其操作数之后来简化计算。在后缀...

    基于C++进行表达式树的建立和遍历(高级语言程序设计实验)

    在本实验中,我们关注的是中序遍历和后序遍历,因为它们分别对应生成中缀表达式和后缀表达式。 - **中序遍历**:对于表达式树,中序遍历顺序是左子树-根节点-右子树。对于计算目的,这将按照操作数-操作符-操作数的...

Global site tag (gtag.js) - Google Analytics