`
128kj
  • 浏览: 604161 次
  • 来自: ...
社区版块
存档分类
最新评论

中缀表达式转后缀表达式并求值(java)

阅读更多
   前缀表达式、中缀表达式和后缀表达式都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。它们之间的区别在于运算符相对与操作数的位置不同:前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。

举例:
(3 + 4) × 5 - 6 就是中缀表达式
- × + 3 4 5 6 前缀表达式
3 4 + 5 × 6 - 后缀表达式

中缀表达式(中缀记法)
  中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。中缀表达式是人们常用的算术表示方法。
  虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。对计算机来说,计算前缀或后缀表达式的值非常简单。

前缀表达式(前缀记法、波兰式)
   前缀表达式的运算符位于操作数之前。

后缀表达式与前缀表达式类似,只是运算符位于操作数之后。


1、将中缀表达式转换为后缀表达式:

(1)当读到数字直接送至输出队列中;
(2)当读到运算符t时:
     a.将栈中所有优先级高于或等于t的运算符弹出,送到输出队列中;
   b.t进栈;
(3)读到左括号时总是将它压入栈中;
(4)读到右括号时,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号;
(5)中缀表达式全部读完后,若栈中仍有运算符,将其送到输出队列中。

2、 运用后缀表达式进行计算:
   (1)建立一个栈S;
   (2)从左到右读后缀表达式,读到数字就将它转换为数值压入栈S中,读到运算符则从栈中依次弹出两个数分别到Y和X,然后以“X 运算符 Y”的形式计算机出结果,再压加栈S中;
   (3)如果后缀表达式未读完,就重复上面过程,最后输出栈顶的数值则为结束。

import java.util.Stack;
import java.util.regex.*;

public class StringToArithmetic {
    private StringToArithmetic() {
    }

    /**
     * 给出一个算术表达式,返回结果。 例如 (5+8+10)*1,返回23
     * 
     * @param string
     */
    public static double stringToArithmetic(String string) {
        return suffixToArithmetic(infixToSuffix(string));
    }

    /**
     * 中缀表达式转后缀表达式
     * 只处理了+,-,*,/和括号,没有处理负号及其它运算符,也没对前缀表达式验证。
     * 如要处理负号,可对表达式进行预转义处理,当下面条件成立时,将负号换成单目运算符"!"
     *    infix.charAt[i]=='-'&&( i==0||infix.charAt[i-1]=='(')
     */
    private static String infixToSuffix(String infix) {
        Stack<Character> stack = new Stack<Character>();
        String suffix = "";
        int length = infix.length();
        for (int i = 0; i < length; i++) {
            Character temp;
            char c = infix.charAt(i);
            switch (c) {
            // 忽略空格
            case ' ':
                break;
            // 碰到'(',push到栈
            case '(':
                stack.push(c);
                break;
            // 碰到'+''-',将栈中所有运算符弹出,送到输出队列中
            case '+':
            case '-':
                while (stack.size() != 0) {
                    temp = stack.pop();
                    if (temp == '(') {
                        stack.push('(');
                        break;
                    }
                    suffix += " " + temp;
                }
                stack.push(c);
                suffix += " ";
                break;
            // 碰到'*''/',将栈中所有乘除运算符弹出,送到输出队列中
            case '*':
            case '/':
                while (stack.size() != 0) {
                    temp = stack.pop();
                    if (temp == '(' || temp == '+' || temp == '-') {
                        stack.push(temp);
                        break;
                    } else {
                        suffix += " " + temp;
                    }
                }
                stack.push(c);
                suffix += " ";
                break;
        // 碰到右括号,将靠近栈顶的第一个左括号上面的运算符全部依次弹出,送至输出队列后,再丢弃左括号
            case ')':
                while (stack.size() != 0) {
                    temp = stack.pop();
                    if (temp == '(')
                        break;
                    else
                        suffix += " " + temp;
                }
                //suffix += " ";
                break;
            default:
                suffix += c;
            }
        }
        while (stack.size() != 0)
            suffix += " " + stack.pop();
        return suffix;
    }

    public static void main(String args[]){
         System.out.println(infixToSuffix("3+(2-5)*6/3"));
         System.out.println(stringToArithmetic("3+(2-5)*6/3"));
    }

    /**
     * 通过后缀表达式求出算术结果
     * 
     * @param String
     *            postfix
     * @return double
     */
    private static double suffixToArithmetic(String postfix) {
        Pattern pattern = Pattern.compile("\\d+||(\\d+\\.\\d+)"); // 匹配数字
        String strings[] = postfix.split(" ");
        for (int i = 0; i < strings.length; i++)
          strings[i].trim();
       Stack<Double> stack = new Stack<Double>();
        for (int i = 0; i < strings.length; i++) {
            
            if (strings[i].equals(""))
                continue;
            if ((pattern.matcher(strings[i])).matches()) {
               
                stack.push(Double.parseDouble(strings[i]));
            } else {
               
                double y = stack.pop();
                double x = stack.pop();
                stack.push(caculate(x, y, strings[i]));
            }
        }
        return stack.pop();
      
       
    }

    private static double caculate(double x, double y, String simble) {
        if (simble.trim().equals("+"))
            return x + y;
        if (simble.trim().equals("-"))
            return x - y;
        if (simble.trim().equals("*"))
            return x * y;
        if (simble.trim().equals("/"))
            return x / y;
        return 0;
    }
}


下载源码:
分享到:
评论
1 楼 hesihua 2013-03-14  
其中存在负数的时候似乎你这道程序通不过额
比如说表达式: -2 + 2 * 3 / 2 - 1
这个就会报错:
Exception in thread "main" java.util.EmptyStackException
at java.util.Stack.peek(Stack.java:85)
at java.util.Stack.pop(Stack.java:67)
at test1.Test.suffixToArithmetic(Test.java:100)
at test1.Test.main(Test.java:120)

相关推荐

    将中缀表达式转换为后缀表达式并求值实验报告

    2. 利用后缀表达式计算表达式的值并输出结果。 3. 检查输入的中缀表达式是否合法。 实验内容主要包括以下几个模块: 1. 构建链栈:链栈是一种线性结构,用于存储数据,支持压栈和弹栈操作。 2. 输入数据:用户在...

    c语言实现中缀表达式转后缀并求值

    c语言实现中缀表达式转后缀表达式并求得计算结果,用顺序栈结构。 当输入者输入错误信息的时候需要报错,并说明错误的种类。

    自定义栈中缀表达式转换为后缀表达式并求值

    ### 自定义栈中缀表达式转换为后缀表达式并求值 #### 需求分析与背景 在计算机科学领域,将一个中缀表达式转换为后缀表达式是解决算术表达式求值问题的一种常用方法。通过这种方式可以避免括号带来的优先级问题,...

    中缀表达式转成后缀表达式并输出计算结果

    用户输入中缀表达式,程序输出后缀表达式并输出计算结果

    C语言实现中缀表达式转化后缀表达式

    利用C语言实现中缀表达式转化为后缀表达式!!利用栈。

    中缀表达式转后缀表达式计算

    按照惯例,算术表达式一般都写成中缀形式,即运算符总是出现在两个操作数之间,单目运算符除外),称为中缀表达式.编译系统对中缀表达式的处理方法是先把它转换为后后缀表达式.... (2) 根据后缀表达式计算表达式的值;

    数据结构的中缀表达式转后缀表达式使用C++实现

    在计算机科学中,数据...总结来说,中缀表达式转后缀表达式是数据结构和算法中的一个经典问题,主要利用堆栈数据结构和运算符优先级规则。在C++中实现这一转换,可以提高计算效率,便于计算机解析和执行数学表达式。

    中缀表达式转后缀表达式

    本项目的目标是实现一个C++程序,它能够接收用户输入的中缀表达式,将其转换为后缀表达式,并计算出结果。这个过程涉及到以下几个关键知识点: 1. **优先级与结合性**:运算符有不同的优先级和结合性,例如乘法和除...

    中缀表达式转后缀表达式源程序(二叉树)

    一个简单的算法,利用栈实现中缀表达式与后缀表达式的转换

    Java 中缀表达转后缀表达式(多位数,带计算)

    本文将详细介绍如何使用Java语言实现中缀表达式到后缀表达式的转换,并进一步计算该表达式的值,特别支持多位数字和复杂运算,包括三角函数(正弦、余弦)、开方、幂和平方等。 #### 转换算法原理 中缀转后缀的...

    中缀表达式转后缀并求值

    C++的代码中缀表达式转后缀然后求值,数据结构方面的。

    数据结构(中缀表达式转后缀表达式)

    /*程序由本人编译,并且经过多次测试,正确无误!目前该转换算法只支持数字在0至9之间的+-*/四元运算转换.*/ /**************程序员信息 ***************东北大学*******************东大很厉害**************** ...

    java堆栈的应用--中缀表达式转换成后缀表达式和计算

    在项目“101544246张绪鹏--中缀转换为后缀表达式及其计算”中,开发者可能实现了一个完整的Java程序,该程序能够读取用户输入的中缀表达式,将其转换为后缀表达式,并根据后缀表达式计算出结果。程序可能包含以下几...

    数据结构实验报告-栈与队列-中缀表达式转换为后缀式5分-实验内容及要求.docx

    算法的设计围绕着如何正确地处理输入的中缀表达式,并将其转换为后缀表达式。具体步骤如下: 1. **读取中缀表达式**:从键盘读入中缀表达式,以字符`=`作为结束符。 2. **处理符号**: - 如果读入的是数字(字符0-...

    中缀表达式转后缀表达式。求值

    这里我们关注的是将中缀表达式转换为后缀表达式(也称为逆波兰表示法),并进行求值。中缀表达式是我们日常数学计算中常用的格式,其中运算符位于操作数之间,例如 `2 + 3`。而后缀表达式则将运算符置于操作数之后,...

    中缀表达式变后缀表达式的求值

    中缀表达式转后缀表达式的算法通常包含两个主要步骤:扫描和输出。首先,我们需要扫描整个中缀表达式,遇到数字时直接输出,遇到操作符时根据优先级与栈顶操作符进行比较,如果当前操作符优先级更高或者栈为空,则压...

    Java中缀表达式求值

    Java中缀表达式求值 Java中缀表达式求值是一种常见的计算机算法,用于评估中缀表达式的值。中缀表达式是一种常见的数学表达式形式,但是在计算机中难以直接计算,因为它的运算符优先级和结合性规则使得计算变得复杂...

    c语言实现中缀表达式向后缀表达式转换

    本篇文章将详细探讨如何通过C语言实现中缀表达式到后缀表达式转换的过程,并具体分析所涉及的关键算法与数据结构。 #### 中缀表达式与后缀表达式简介 - **中缀表达式**:我们日常使用的数学表达式,如 `3 + 4 * 2`...

Global site tag (gtag.js) - Google Analytics