数学表达式解析前缀中缀后缀.docx

上传人:b****8 文档编号:9228603 上传时间:2023-02-03 格式:DOCX 页数:19 大小:21.38KB
下载 相关 举报
数学表达式解析前缀中缀后缀.docx_第1页
第1页 / 共19页
数学表达式解析前缀中缀后缀.docx_第2页
第2页 / 共19页
数学表达式解析前缀中缀后缀.docx_第3页
第3页 / 共19页
数学表达式解析前缀中缀后缀.docx_第4页
第4页 / 共19页
数学表达式解析前缀中缀后缀.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

数学表达式解析前缀中缀后缀.docx

《数学表达式解析前缀中缀后缀.docx》由会员分享,可在线阅读,更多相关《数学表达式解析前缀中缀后缀.docx(19页珍藏版)》请在冰豆网上搜索。

数学表达式解析前缀中缀后缀.docx

数学表达式解析前缀中缀后缀

前缀、中缀、后缀表达式

它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记法。

它们之间的区别在于运算符相对与操作数的位置不同:

前缀表达式的运算符位于与其相关的操作数之前;中缀和后缀同理。

举例:

(3+4)×5-6就是中缀表达式

-×+3456 前缀表达式

34+5×6- 后缀表达式

中缀表达式(中缀记法)

中缀表达式是一种通用的算术或逻辑公式表示方法,操作符以中缀形式处于操作数的中间。

中缀表达式是人们常用的算术表示方法。

虽然人的大脑很容易理解与分析中缀表达式,但对计算机来说中缀表达式却是很复杂的,因此计算表达式的值时,通常需要先将中缀表达式转换为前缀或后缀表达式,然后再进行求值。

对计算机来说,计算前缀或后缀表达式的值非常简单。

前缀表达式(前缀记法、波兰式)

前缀表达式的运算符位于操作数之前。

前缀表达式的计算机求值:

从右至左扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(栈顶元素op次顶元素),并将结果入栈;重复上述过程直到表达式最左端,最后运算得出的值即为表达式的结果。

例如前缀表达式“-×+3456”:

(1)从右至左扫描,将6、5、4、3压入堆栈;

(2)遇到+运算符,因此弹出3和4(3为栈顶元素,4为次顶元素,注意与后缀表达式做比较),计算出3+4的值,得7,再将7入栈;

(3)接下来是×运算符,因此弹出7和5,计算出7×5=35,将35入栈;

(4)最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

可以看出,用计算机计算前缀表达式的值是很容易的。

将中缀表达式转换为前缀表达式:

遵循以下步骤:

(1)初始化两个栈:

运算符栈S1和储存中间结果的栈S2;

(2)从右至左扫描中缀表达式;

(3)遇到操作数时,将其压入S2;

(4)遇到运算符时,比较其与S1栈顶运算符的优先级:

(4-1)如果S1为空,或栈顶运算符为右括号“)”,则直接将此运算符入栈;

(4-2)否则,若优先级比栈顶运算符的较高或相等,也将运算符压入S1;

(4-3)否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;

(5)遇到括号时:

(5-1)如果是右括号“)”,则直接压入S1;

(5-2)如果是左括号“(”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到右括号为止,此时将这一对括号丢弃;

(6)重复步骤

(2)至(5),直到表达式的最左边;

(7)将S1中剩余的运算符依次弹出并压入S2;

(8)依次弹出S2中的元素并输出,结果即为中缀表达式对应的前缀表达式。

例如,将中缀表达式“1+((2+3)×4)-5”转换为前缀表达式的过程如下:

扫描到的元素

S2(栈底->栈顶)

S1(栈底->栈顶)

说明

5

5

数字,直接入栈

-

5

-

S1为空,运算符直接入栈

5

-)

右括号直接入栈

4

54

-)

数字直接入栈

×

54

-)×

S1栈顶是右括号,直接入栈

54

-)×)

右括号直接入栈

3

543

-)×)

数字

+

543

-)×)+

S1栈顶是右括号,直接入栈

2

5432

-)×)+

数字

5432+

-)×

左括号,弹出运算符直至遇到右括号

5432+×

-

同上

+

5432+×

-+

优先级与-相同,入栈

1

5432+×1

-+

数字

到达最左端

5432+×1+-

S1中剩余的运算符

因此结果为“-+1×+2345”。

后缀表达式(后缀记法、逆波兰式)

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

后缀表达式的计算机求值:

与前缀表达式类似,只是顺序是从左至右:

从左至右扫描表达式,遇到数字时,将数字压入堆栈,遇到运算符时,弹出栈顶的两个数,用运算符对它们做相应的计算(次顶元素op 栈顶元素),并将结果入栈;重复上述过程直到表达式最右端,最后运算得出的值即为表达式的结果。

例如后缀表达式“34+5×6-”:

(1)从左至右扫描,将3和4压入堆栈;

(2)遇到+运算符,因此弹出4和3(4为栈顶元素,3为次顶元素,注意与前缀表达式做比较),计算出3+4的值,得7,再将7入栈;

(3)将5入栈;

(4) 接下来是×运算符,因此弹出5和7,计算出7×5=35,将35入栈;

(5)将6入栈;

(6)最后是-运算符,计算出35-6的值,即29,由此得出最终结果。

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

与转换为前缀表达式相似,遵循以下步骤:

(1)初始化两个栈:

运算符栈S1和储存中间结果的栈S2;

(2)从左至右扫描中缀表达式;

(3)遇到操作数时,将其压入S2;

(4)遇到运算符时,比较其与S1栈顶运算符的优先级:

(4-1)如果S1为空,或栈顶运算符为左括号“(”,则直接将此运算符入栈;

(4-2)否则,若优先级比栈顶运算符的高,也将运算符压入S1(注意转换为前缀表达式时是优先级较高或相同,而这里则不包括相同的情况);

(4-3)否则,将S1栈顶的运算符弹出并压入到S2中,再次转到(4-1)与S1中新的栈顶运算符相比较;

(5)遇到括号时:

(5-1)如果是左括号“(”,则直接压入S1;

(5-2)如果是右括号“)”,则依次弹出S1栈顶的运算符,并压入S2,直到遇到左括号为止,此时将这一对括号丢弃;

(6)重复步骤

(2)至(5),直到表达式的最右边;

(7)将S1中剩余的运算符依次弹出并压入S2;

(8)依次弹出S2中的元素并输出,结果的逆序即为中缀表达式对应的后缀表达式(转换为前缀表达式时不用逆序)。

例如,将中缀表达式“1+((2+3)×4)-5”转换为后缀表达式的过程如下:

扫描到的元素

S2(栈底->栈顶)

S1(栈底->栈顶)

说明

1

1

数字,直接入栈

+

1

+

S1为空,运算符直接入栈

1

+(

左括号,直接入栈

1

+((

同上

2

12

+((

数字

+

12

+((+

S1栈顶为左括号,运算符直接入栈

3

123

+((+

数字

123+

+(

右括号,弹出运算符直至遇到左括号

×

123+

+(×

S1栈顶为左括号,运算符直接入栈

4

123+4

+(×

数字

123+4×

+

右括号,弹出运算符直至遇到左括号

-

123+4×+

-

-与+优先级相同,因此弹出+,再压入-

5

123+4×+5

-

数字

到达最右端

123+4×+5-

S1中剩余的运算符

因此结果为“123+4×+5-”(注意需要逆序输出)。

编写Java程序将一个中缀表达式转换为前缀表达式和后缀表达式,并计算表达式的值。

其中的toPolishNotation()方法将中缀表达式转换为前缀表达式(波兰式)、toReversePolishNotation()方法则用于将中缀表达式转换为后缀表达式(逆波兰式):

注:

(1)程序很长且注释比较少,但如果将上面的理论内容弄懂之后再将程序编译并运行起来,还是比较容易理解的。

有耐心的话可以研究一下。

(2)此程序是笔者为了说明上述概念而编写,仅做了简单的测试,不保证其中没有Bug,因此不要将其用于除研究之外的其他场合。

[java] viewplain copy

1.package qmk.simple_test;  

2.import java.util.Scanner;  

3.import java.util.Stack;  

4./** 

5. * Example of converting an infix-expression to 

6. * Polish Notation (PN) or Reverse Polish Notation (RPN). 

7. * Written in 2011-8-25 

8. * @author QiaoMingkui 

9. */  

10.public class Calculator {  

11.      public static final String USAGE = "== usage ==\n"  

12.            + "input the expressions, and then the program "  

13.            + "will calculate them and show the result.\n"  

14.            + "input 'bye' to exit.\n";  

15.      /** 

16.       * @param args 

17.       */  

18.      public static void main(String[] args) {  

19.            System.out.println(USAGE);  

20.            Scanner scanner = new Scanner(System.in);  

21.            String input = "";  

22.            final String CLOSE_MARK = "bye";  

23.            System.out.println("input an expression:

");  

24.            input = scanner.nextLine();  

25.            while (input.length() !

= 0  

26.                  && !

CLOSE_MARK.equals((input))) {  

27.                  System.out.print("Polish Notation (PN):

");  

28.                  try {  

29.                        toPolishNotation(input);  

30.                  } catch (NumberFormatException e) {  

31.                        System.out.println("\ninput error, not a number.");  

32.                  } catch (IllegalArgumentException e) {  

33.                        System.out.println("\ninput error:

" + e.getMessage());  

34.                  } catch (Exception e) {  

35.                        System.out.println("\ninput error, invalid expression.");  

36.                  }  

37.                  System.out.print("Reverse Polish Notation (RPN):

");  

38.                  try {  

39.                        toReversePolishNotation(input);  

40.                  } catch (NumberFormatException e) {  

41.                        System.out.println("\ninput error, not a number.");  

42.                  } catch (IllegalArgumentException e) {  

43.                        System.out.println("\ninput error:

" + e.getMessage());  

44.                  } catch (Exception e) {  

45.                        System.out.println("\ninput error, invalid expression.");  

46.                  }  

47.                  System.out.println("input a new expression:

");  

48.                  input = scanner.nextLine();  

49.            }  

50.            System.out.println("program exits");  

51.      }  

52.      /** 

53.       * parse the expression , and calculate it. 

54.       * @param input 

55.       * @throws IllegalArgumentException 

56.       * @throws NumberFormatException 

57.       */  

58.      private static void toPolishNotation(String input)  

59.                  throws IllegalArgumentException, NumberFormatException {  

60.            int len = input.length();  

61.            char c, tempChar;  

62.            Stack s1 = new Stack();  

63.            Stack s2 = new Stack();  

64.            Stack expression = new Stack();  

65.            double number;  

66.            int lastIndex = -1;  

67.            for (int i=len-1; i>=0; --i) {  

68.                  c = input.charAt(i);  

69.                  if (Character.isDigit(c)) {  

70.                        lastIndex = readDoubleReverse(input, i);  

71.                        number = Double.parseDouble(input.substring(lastIndex, i+1));  

72.                        s2.push(number);  

73.                        i = lastIndex;  

74.                        if ((int) number == number)  

75.                              expression.push((int) number);  

76.                        else  

77.                              expression.push(number);  

78.                  } else if (isOperator(c)) {  

79.                        while (!

s1.isEmpty()  

80.                                    && s1.peek() !

= ')'  

81.                                    && priorityCompare(c, s1.peek()) < 0) {  

82.                              expression.push(s1.peek());  

83.                              s2.push(calc(s2.pop(), s2.pop(), s1.pop()));  

84.                        }  

85.                        s1.push(c);  

86.                  } else if (c == ')') {  

87.                        s1.push(c);  

88.                  } else if (c == '(') {  

89.                        while ((tempChar=s1.pop()) !

= ')') {  

90.                              expression.push(tempChar);  

91.                              s2.push(calc(s2.pop(), s2.pop(), tempChar));  

92.                              if (s1.isEmpty()) {  

93.                                    throw new IllegalArgumentException(  

94.                                          "bracket dosen't match, missing right bracket ')'.");  

95.                              }  

96.                        }  

97.                  } else if (c == ' ') {  

98.                        // ignore  

99.                  } else {  

100.                        throw new IllegalArgumentException(  

101.                                    "wrong character '" + c + "'");  

102.                  }  

103.            }  

104.            while (!

s1.isEmpty()) {  

105.                  tempChar = s1.pop();  

106.                  expression.push(tempChar);  

107.                  s2.push(calc(s2.pop(), s2.pop(), tempChar));  

108.            }  

109.            while (!

expression.isEmpty()) {  

110.                  System.out.print(expression.pop() + " ");  

111.            }  

112.            double result = s2.pop();  

113.            if (!

s2.isEmpty())  

114.                  throw new IllegalArgumentException("input is a wrong expression.");  

115.            System.out.println();  

116.            if ((int) result == result)  

117.                  System.out.println("the result is " + (int) result);  

118.            else  

119.                  System.out.println("the result is " + result);  

120.      }  

121.      /** 

122.       * parse the expression, and calculate it. 

123.       * @param input 

124.       * @throws IllegalArgumentException 

125.       * @throws NumberFormatException 

126.       */  

127.      private static void toReversePolishNotation(String input)  

128.                  throws IllegalArgumentException, NumberFormatException {  

129.            int len = input.le

展开阅读全文
相关搜索

当前位置:首页 > 解决方案 > 学习计划

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1