`
where
  • 浏览: 81725 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

Java实现由中缀表达式转为前缀表达式

阅读更多

      PS:

     这段时间一直在找实习,在这条路上的风景对我来说并不是那么写意,期间发现自己的知识还是不成体系,平时用的很多的东西在表达时就完全不是那么回事了。姑且把这看成一个学习的过程吧,接下来我会陆续的把这些题重做一次,希望会得到成长!那么就从最近的“前缀表达式”开始吧! 接下来的内容将围绕这两个问题展开:

1.为什么要把中缀表达式转化成前缀表达式?

2.怎么把中缀表达式转化成前缀表达式并计算(描述并JAVA实现)?

一. 先来回答为什么要把中缀表达式转化成前缀表达式?

中缀表达式(或中缀记法)是一个通用的算术或逻辑公式表示方法,与前缀表达式(例:+ 3 4)或后缀表达式(例:3 4 +)相比,中缀表达式不容易被计算机解析,但仍被许多程序语言使用,因为它符合人们的普遍用法。

二. 怎么把中缀表达式转化成前缀表达式并计算?

 

      前缀表达式
     前缀表达式就是前序表达式
      前缀表达式就是不含括号的算术表达式,而且它是将运算符写在前面,操作数写在后面的表达式,为纪念其发明者波兰数学家Jan Lukasiewicz也称为“波兰式”。例如,- 1 + 2 3,它等价于1-(2+3)。
     由中缀表达式转为前缀表达式的步骤
1. 初始化两个栈:运算符栈S1和储存中间结果的栈S2;
2. 从右至左扫描中缀表达式;
3. 遇到操作数时,将其压入S2;
4. 遇到运算符时,比较其与S1栈顶运算符的优先级:
  • 如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;
  • 否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;
  • 否则,将S1栈顶的运算符弹出并压入到S2中,再与S1中新的栈顶运算符相比较;
5. 遇到括号时:
  •   如果是右括号“)”,则直接压入S1;
  •  如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号 丢弃;
6. 重复步骤2至5,直到表达式的最左边;
7. 将S1中剩余的运算符依次弹出并压入S2;
8. 依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。
    例如,将中缀表达式“(3+4)-5*9”转换为前缀表达式的过程如下:
扫描到的元素 S2(栈底->栈顶) S1 (栈底->栈顶) 说明
6 6 数字直接入栈
* 6 * S1为空,运算符直接入栈
5 65 * 数字直接入栈
- 65* - 优先级小于栈顶元素
) 65* -) 右括号直接入栈
4 654* -) 数字直接入栈
+ 654* -)+ S1栈顶是右括号,直接入栈
3 6543* -)+ 数字直接入栈
( 6543*+- 左括号,弹出运算符直至遇到右括号
到达最左端 6543*+- S1中剩余的运算符
    
      JAVA代码实现:
import java.util.Stack;
/**
 * 以整型数为例测试中缀表达式转换成前缀表达式的计算问题
 * @author where
 *
 */
public class TestForExpression {

      public static void main(String[] args) {
          String input_expression = "(3+4)-5*9" ;
          System. out .println("待测试的中缀表达式为:" +input_expression);
          System. out .print("相应的前缀表达式为:" );
           toPrefixExpression(input_expression);

     }
      /**
      * 将中缀表达式转化为前缀表达式
      * @param input 要被转化的中缀表达式
      */
      public static void  toPrefixExpression(String input){
           int len = input.length();//中缀表达式的长度
           //System.out.println("读到的字符串为:"+input+"长度为:"+ len);
           char c,tempChar;//这两个都是中间变量,c用来存放循环中的对应位置的字符,
          Stack<Character> s1 = new Stack<Character>();//实例化一个符号栈
          Stack<Integer> s2 = new Stack<Integer>();//实例化一个数字栈
          Stack< Object> expression = new Stack< Object>();  //实例化一个前缀表达式的栈
           //从右至左扫描表达式
           for (int i=len-1; i>=0; --i) { 
             c = input.charAt(i);
             //判断读取的是不是数字,是的话将数字压入操作数栈和表达式栈
             if (Character.isDigit(c)) {
               String s = String. valueOf(c);
               //再转换成 Int类型:
               int j = Integer.parseInt(s);
                   s2.push(j); 
                   expression.push(j); 
             } else if (isOperator(c)) {
               //如果当前字符为运算符(包含括号)
                   while (!s1.isEmpty() 
                               && s1.peek() != ')' 
                               && priorityCompare(c, s1.peek()) < 0) { 
                      //当前运算符栈不为空且要运算符栈顶运算符不是右括号且当前运算符的优先级比运算符栈顶运算符的优先级低,
                      //则将运算符栈栈顶元素拿出来与操作数栈的两个栈顶元素进行运算并把运算结果压入操作数栈
                         expression.push(s1.peek()); 
                         s2.push( calc(s2.pop(), s2.pop(), s1.pop())); 
                   } 
                   s1.push(c); 
             } else if (c == ')' ) {
               //因为我们是从右至左来扫描中缀表达式的所以对于一个“()”而言一定是先读到右边的括号
                   s1.push(c); 
             } else if (c == '(' ) { 
               //如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入表达式栈,直到遇到左括号为止,此时将这一对括号丢弃;
                   while ((tempChar=s1.pop()) != ')' ) { 
                         expression.push(tempChar); 
                         s2.push( calc(s2.pop(), s2.pop(), tempChar)); 
                         if (s1.isEmpty()) { 
                               throw new IllegalArgumentException( 
                                     "bracket dosen't match, missing right bracket ')'."); 
                         } 
                   } 
             } else if (c == ' ' ) { 
                   // 如果表达式里包含空格则不处理空格
             } else { 
                   throw new IllegalArgumentException( 
                               "wrong character '" + c + "'" ); 
             } 
           }
           while (!s1.isEmpty()) { 
             tempChar = s1.pop(); 
             expression.push(tempChar); 
             s2.push( calc(s2.pop(), s2.pop(), tempChar)); 
           } 
           while (!expression.isEmpty()) { 
             System. out .print(expression.pop() + " " ); 
           } 
           int result = s2.pop(); 
           if (!s2.isEmpty()) 
             throw new IllegalArgumentException( "input is a wrong expression.");  
           System. out .println(); 
         System. out .println("计算结果为: " + result); 
          
     }
      /**
      * 对给定的两个操作数及操作符进行计算
      * @param num1
      * @param num2
      * @param op
      * @return 返回计算整型结果
      */
      private static Integer calc( int num1, int num2, char op) {
       
            switch (op) { 
            case '+' : 
                  return num1 + num2; 
            case '-' : 
                  return num1 - num2; 
            case '*' : 
                  return num1 * num2; 
            case '/' : 
                  if (num2 == 0) throw new IllegalArgumentException("divisor can't be 0." ); 
                  return num1 / num2; 
            default : 
                  return 0; // will never catch up here 
            } 
       
     }
      /**
      * 判断字符是否是操作符的方法
      * @param c
      * @return
      */
      private static boolean isOperator( char c) {
                return (c=='+' || c=='-' || c=='*' || c=='/' ); 
     }
      /**
      * 判断运算符优先级的方法
      * @param op1
      * @param op2
      * @return 返回值如果是:
      *          - 1则表示op1的优先级低于op2,
      *           0 则表示op1的优先级等于op2,
      *           1则表示op1的优先级高于op2。
      */
      private static int priorityCompare( char op1, char op2) { 
         switch (op1) { 
         case '+' : case '-': 
               return (op2 == '*' || op2 == '/' ? -1 : 0); 
         case '*' : case '/': 
               return (op2 == '+' || op2 == '-' ? 1 : 0); 
         } 
         return 1; 
   } 
 

}
   测试结果:
待测试的中缀表达式为:(3+4)-5*9
相应的前缀表达式为:- + 3 4 * 5 9 
计算结果为: -38
 (说明:为了方便说明整个转化方法,我已整型运算为例,如果要考虑的更全面的话可以用               Double型,只不过在对“.”的时候要注意)
时间不早了,明天还有课,博客就先写到这,明天继续下一题搞起!!!

 

       

 

1
2
分享到:
评论

相关推荐

    栈和队列的应用实验 利用栈实现中缀表达式与前缀表达式的转换

    2、利用栈实现中缀表达式与前缀表达式的转换。 三、相关内容介绍 标准的表达式如"A+B",在数学上学名叫中缀表达式(Infix Notation),原因是运算符号在两个运算对象的中间。相对应的还有前缀表达式(Prefix ...

    中缀表达式输入、转换与计算(前缀和后缀)内附流程图

    表达式2*(9+6/3-5)+4,称为中缀表达式,表示成2 9 6 3 / + 5 - * 4 +称为后缀表达式,表示成+ * 2 - + 9 / 6 3 5 4称为前缀表达式。 ·基本要求 将中缀表达式,转换为后缀表达式和前缀表达式,再分别计算转换后的...

    中缀表达式与前缀表达式的转换

    下面是一个使用 C++ 语言实现的中缀表达式与前缀表达式的转换算法: ```c #include #include using namespace std; char stack[50];//定义顺序栈,其中第一个元素表示栈为空; int top=0;//栈顶指针,为 0 表示栈为...

    前缀表达式、中缀表达式和后缀表达式 - 乘月归 - 博客园.pdf

    前缀表达式、中缀表达式和后缀表达式是编程中常见的三种表达式表示方法,它们在计算机程序设计和算法中扮演着重要的角色。中缀表达式是最常见的一种,例如在普通的算术运算中就广泛使用。而后缀表达式和前缀表达式则...

    用二叉树实现中缀表达式转换成后缀表达式

    C++实现中,你可以使用`std::stack`容器来模拟栈,`std::string`来存储后缀表达式,同时使用`std::stringstream`来处理中缀表达式中的操作数和运算符。以下是一个简单的C++代码框架: ```cpp #include #include #...

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

    ### C语言实现中缀表达式向后缀表达式转换 #### 概述 在计算机科学领域,表达式的处理是一项基础而重要的任务。表达式通常有三种形式:前缀(波兰)、中缀(标准数学表达式)和后缀(逆波兰)。本篇文章将详细探讨...

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

    通过上述分析,我们可以看到Java实现中缀表达式到后缀表达式的转换以及后续的计算涉及到了栈数据结构的应用,以及对各种运算符优先级的正确处理。这种转换方法不仅能够简化表达式的计算流程,还能有效支持包括多位...

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

    将一个表达式转为后缀表达式,用堆栈计算 中缀转后缀的过程中遇到数字直接输出,遇到符号则判断优先级。

    前缀表达式 求值 转换 中缀表达式

    对前缀表达式进行 求值 并转换 中缀表达式

    将中缀表达式变后缀表达式,对你绝对有用哦

    在计算机科学中,算术表达式有三种主要的表示形式:中缀表达式、前缀表达式和后缀表达式。其中,中缀表达式是我们日常生活中最常用的表示方式,如“3 + 4 * 5”,运算符位于操作数之间。而后缀表达式(也称为逆波兰...

    中缀表达式计算C++实现

    本主题主要探讨如何使用C++语言来实现中缀表达式的计算。 首先,我们需要理解中缀表达式的计算原理。这通常涉及到两个关键步骤:语法分析(将中缀表达式转换为抽象语法树AST)和求值(遍历AST并执行相应的运算)。...

    从中缀向后缀转换表达式

    我们所要设计并实现的程序就是将中缀表示的算术表达式转换成后缀表示,例如,将中缀表达式 (A 一 (B*C 十 D)*E) / (F 十 G ) 转换为后缀表示为: ABC*D十E*—FG十/ 注意:为了简化编程实现,假定变量名均为...

    中缀表达式求值

    本实验主要关注如何使用数据结构,特别是栈,来实现中缀表达式的求值。 首先,我们要了解栈是一种具有“后进先出”(LIFO)特性的数据结构,非常适合处理中缀表达式。在计算中缀表达式时,我们通常会用到两个栈:一...

    中缀表达式修改_中缀求值_

    本文将深入探讨如何将中缀表达式转换为后缀表达式,并利用堆栈实现中缀表达式的求值。 首先,我们来看一下中缀表达式到后缀表达式的转换。这个过程主要通过两个步骤完成:遍历表达式并将其分为操作符和操作数,然后...

    C#中缀表达式计算器

    在C#中实现一个中缀表达式计算器可以帮助开发者理解操作符优先级和如何利用数据结构来解决问题。 首先,我们需要了解栈(Stack)这种数据结构。栈是一种后进先出(LIFO)的数据结构,即最后存入的数据最先被取出。...

    表达式树 中缀表达式转后缀

    本文将详细讨论如何将中缀表达式转换为后缀表达式(也称为逆波兰表示法),并结合“表达式树”这一概念进行阐述。在这个过程中,我们将使用VC6.0作为开发环境,但它同样适用于其他编程语言和环境。 首先,我们了解...

    具有表达式的中缀表达式求值程序

    因此,通常会先将中缀表达式转换为后缀或前缀表达式再进行计算。 #### 数据结构定义 程序首先定义了一些必要的数据结构: 1. **ComStack**:一种特殊的栈结构,用于存放浮点型数值。 ```c typedef float DataType...

    C++ 数据结构 二叉树解决中缀表达式的计算

    中缀表达式是我们日常生活中最常见的数学表达式形式,如2 + 3 * 4,但在计算机处理时,为了便于解析和计算,通常会将其转化为前缀或后缀表达式(即波兰表示法和逆波兰表示法)。然而,通过构建特定的二叉树结构——...

    前缀转换后缀中缀表达式

    将前缀表达式转换为中缀表达式则稍显复杂,因为需要处理括号和运算符优先级。基本策略是: 1. 初始化一个空栈,用于存放运算符。 2. 从左到右遍历前缀表达式,遇到操作数直接输出,遇到运算符则压栈。 3. 当遇到左...

    用“中缀表达式”实现计算器部分功能,c++

    在这个项目中,我们将探讨如何使用C++编程语言来实现一个基于中缀表达式的计算器,以解决这类计算问题。 首先,我们需要理解中缀表达式到后缀表达式的转换过程。这通常通过使用栈数据结构来完成。在看到运算符时,...

Global site tag (gtag.js) - Google Analytics