日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java数据结构和算法(六)——前缀、中缀、后缀表达式

發布時間:2025/3/21 java 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java数据结构和算法(六)——前缀、中缀、后缀表达式 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前面我們介紹了三種數據結構,第一種數組主要用作數據存儲,但是后面的兩種棧和隊列我們說主要作為程序功能實現的輔助工具,其中在介紹棧時我們知道棧可以用來做單詞逆序,匹配關鍵字符等等,那它還有別的什么功能嗎?以及數據結構與本篇博客的主題前綴、中綴、后綴表達式有什么關系呢?

回到頂部

1、人如何解析算術表達式

  如何解析算術表達式?或者換種說法,遇到某個算術表達式,我們是如何計算的:

  ①、求值 3+4-5

  

  這個表達式,我們在看到3+4后都不能直接計算3+4的值,知道看到4后面的 - 號,因為減號的優先級和前面的加號一樣,所以可以計算3+4的值了,如果4后面是 * 或者 /,那么就要在乘除過后才能做加法操作,比如:

  ②、求值 3+4*5

  

?

  這個不能先求3+4的值,因為4后面的*運算級別比前面的+高。通過這兩個表達式的說明,我們可以總結解析表達式的時候遵循的幾條規則:

  ①、從左到右讀取算式。

  ②、已經讀到了可以計算值的兩個操作數和一個操作符時,可以計算,并用計算結果代替那兩個操作數和一個操作符。

  ③、繼續這個過程,從左到右,能算就算,直到表達式的結尾。

?

回到頂部

2、計算機如何解析算術表達式

  對于前面的表達式 3+4-5,我們人是有思維能力的,能根據操作符的位置,以及操作符的優先級別能算出該表達式的結果。但是計算機怎么算?

  計算機必須要向前(從左到右)來讀取操作數和操作符,等到讀取足夠的信息來執行一個運算時,找到兩個操作數和一個操作符進行運算,有時候如果后面是更高級別的操作符或者括號時,就必須推遲運算,必須要解析到后面級別高的運算,然后回頭來執行前面的運算。我們發現這個過程是極其繁瑣的,而計算機是一個機器,只認識高低電平,想要完成一個簡單表達式的計算,我們可能要設計出很復雜的邏輯電路來控制計算過程,那更不用說很復雜的算術表達式,所以這樣來解析算術表達式是不合理的,那么我們應該采取什么辦法呢?

  請大家先看看什么是前綴表達式,中綴表達式,后綴表達式:這三種表達式其實就是算術表達式的三種寫法,以 3+4-5為例

  ①、前綴表達式:操作符在操作數的前面,比如 +-543

  ②、中綴表達式:操作符在操作數的中間,這也是人類最容易識別的算術表達式 3+4-5

  ③、后綴表達式:操作符在操作數的后面,比如 34+5-

  上面我們講的人是如何解析算術表達式的,也就是解析中綴表達式,這是人最容易識別的,但是計算機不容易識別,計算機容易識別的是前綴表達式和后綴表達式,將中綴表達式轉換為前綴表達式或者后綴表達式之后,計算機能很快計算出表達式的值,那么中綴表達式是如何轉換為前綴表達式和后綴表達式,以及計算機是如何解析前綴表達式和后綴表達式來得到結果的呢?

回到頂部

3、后綴表達式

  后綴表達式,指的是不包含括號,運算符放在兩個運算對象的后面,所有的計算按運算符出現的順序,嚴格從左向右進行(不再考慮運算符的優先規則)。

  由于后綴表達式的運算符在兩個操作數的后面,那么計算機在解析后綴表達式的時候,只需要從左向右掃描,也就是只需要向前掃描,而不用回頭掃描,遇到運算符就將運算符放在前面兩個操作符的中間(這里先不考慮乘方類似的單目運算),一直運算到最右邊的運算符,那么就得出運算結果了。既然后綴表達式這么好,那么問題來了:

  ①、如何將中綴表達式轉換為后綴表達式?

  對于這個問題,轉換的規則如下:

  

  一、先自定義一個棧

+ View Code

  二、前綴表達式轉換為后綴表達式

+ View Code

  三、測試

前面我們介紹了三種數據結構,第一種數組主要用作數據存儲,但是后面的兩種棧和隊列我們說主要作為程序功能實現的輔助工具,其中在介紹棧時我們知道棧可以用來做單詞逆序,匹配關鍵字符等等,那它還有別的什么功能嗎?以及數據結構與本篇博客的主題前綴、中綴、后綴表達式有什么關系呢?

回到頂部

1、人如何解析算術表達式

  如何解析算術表達式?或者換種說法,遇到某個算術表達式,我們是如何計算的:

  ①、求值 3+4-5

  

  這個表達式,我們在看到3+4后都不能直接計算3+4的值,知道看到4后面的 - 號,因為減號的優先級和前面的加號一樣,所以可以計算3+4的值了,如果4后面是 * 或者 /,那么就要在乘除過后才能做加法操作,比如:

  ②、求值 3+4*5

  

?

  這個不能先求3+4的值,因為4后面的*運算級別比前面的+高。通過這兩個表達式的說明,我們可以總結解析表達式的時候遵循的幾條規則:

  ①、從左到右讀取算式。

  ②、已經讀到了可以計算值的兩個操作數和一個操作符時,可以計算,并用計算結果代替那兩個操作數和一個操作符。

  ③、繼續這個過程,從左到右,能算就算,直到表達式的結尾。

?

回到頂部

2、計算機如何解析算術表達式

  對于前面的表達式 3+4-5,我們人是有思維能力的,能根據操作符的位置,以及操作符的優先級別能算出該表達式的結果。但是計算機怎么算?

  計算機必須要向前(從左到右)來讀取操作數和操作符,等到讀取足夠的信息來執行一個運算時,找到兩個操作數和一個操作符進行運算,有時候如果后面是更高級別的操作符或者括號時,就必須推遲運算,必須要解析到后面級別高的運算,然后回頭來執行前面的運算。我們發現這個過程是極其繁瑣的,而計算機是一個機器,只認識高低電平,想要完成一個簡單表達式的計算,我們可能要設計出很復雜的邏輯電路來控制計算過程,那更不用說很復雜的算術表達式,所以這樣來解析算術表達式是不合理的,那么我們應該采取什么辦法呢?

  請大家先看看什么是前綴表達式,中綴表達式,后綴表達式:這三種表達式其實就是算術表達式的三種寫法,以 3+4-5為例

  ①、前綴表達式:操作符在操作數的前面,比如 +-543

  ②、中綴表達式:操作符在操作數的中間,這也是人類最容易識別的算術表達式 3+4-5

  ③、后綴表達式:操作符在操作數的后面,比如 34+5-

  上面我們講的人是如何解析算術表達式的,也就是解析中綴表達式,這是人最容易識別的,但是計算機不容易識別,計算機容易識別的是前綴表達式和后綴表達式,將中綴表達式轉換為前綴表達式或者后綴表達式之后,計算機能很快計算出表達式的值,那么中綴表達式是如何轉換為前綴表達式和后綴表達式,以及計算機是如何解析前綴表達式和后綴表達式來得到結果的呢?

回到頂部

3、后綴表達式

  后綴表達式,指的是不包含括號,運算符放在兩個運算對象的后面,所有的計算按運算符出現的順序,嚴格從左向右進行(不再考慮運算符的優先規則)。

  由于后綴表達式的運算符在兩個操作數的后面,那么計算機在解析后綴表達式的時候,只需要從左向右掃描,也就是只需要向前掃描,而不用回頭掃描,遇到運算符就將運算符放在前面兩個操作符的中間(這里先不考慮乘方類似的單目運算),一直運算到最右邊的運算符,那么就得出運算結果了。既然后綴表達式這么好,那么問題來了:

?

  ①、如何將中綴表達式轉換為后綴表達式?

  對于這個問題,轉換的規則如下:

  

  一、先自定義一個棧

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

package?com.ys.poland;

?

public?class?MyCharStack {

????private?char[] array;

????private?int?maxSize;

????private?int?top;

?????

????public?MyCharStack(int?size){

????????this.maxSize = size;

????????array =?new?char[size];

????????top = -1;

????}

?????

????//壓入數據

????public?void?push(char?value){

????????if(top < maxSize-1){

????????????array[++top] = value;

????????}

????}

?????

????//彈出棧頂數據

????public?char?pop(){

????????return?array[top--];

????}

?????

????//訪問棧頂數據

????public?char?peek(){

????????return?array[top];

????}

?????

????//查看指定位置的元素

????public?char?peekN(int?n){

????????return?array[n];

????}

?????

????//為了便于后面分解展示棧中的內容,我們增加了一個遍歷棧的方法(實際上棧只能訪問棧頂元素的)

????public?void?displayStack(){

????????System.out.print("Stack(bottom-->top):");

????????for(int?i =?0?; i < top+1; i++){

????????????System.out.print(peekN(i));

????????????System.out.print(' ');

????????}

????????System.out.println("");

????}

?????

????//判斷棧是否為空

????public?boolean?isEmpty(){

????????return?(top == -1);

????}

?????

????//判斷棧是否滿了

????public?boolean?isFull(){

????????return?(top == maxSize-1);

????}

?

}

  二、前綴表達式轉換為后綴表達式

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

package?com.ys.poland;

?

public?class?InfixToSuffix {

????private?MyCharStack s1;//定義運算符棧

????private?MyCharStack s2;//定義存儲結果棧

????private?String input;

?????

????//默認構造方法,參數為輸入的中綴表達式

????public?InfixToSuffix(String in){

????????input = in;

????????s1 =?new?MyCharStack(input.length());

????????s2 =?new?MyCharStack(input.length());

????}

????//中綴表達式轉換為后綴表達式,將結果存儲在棧中返回,逆序顯示即后綴表達式

????public?MyCharStack doTrans(){

????????for(int?j =?0?; j < input.length() ; j++){

????????????System.out.print("s1棧元素為:");

????????????s1.displayStack();

????????????System.out.print("s2棧元素為:");

????????????s2.displayStack();

????????????char?ch = input.charAt(j);

????????????System.out.println("當前解析的字符:"+ch);

????????????switch?(ch) {

????????????case?'+':

????????????case?'-':

????????????????gotOper(ch,1);

????????????????break;

????????????case?'*':

????????????case?'/':

????????????????gotOper(ch,2);

????????????????break;

????????????case?'(':

????????????????s1.push(ch);//如果當前字符是'(',則將其入棧

????????????????break;

????????????case?')':

????????????????gotParen(ch);

????????????????break;

????????????default:

????????????????//1、如果當前解析的字符是操作數,則直接壓入s2

????????????????//2、

????????????????s2.push(ch);

????????????????break;

????????????}//end switch

????????}//end for

?????????

????????while(!s1.isEmpty()){

????????????s2.push(s1.pop());

????????}

????????return?s2;

????}

?????

????public?void?gotOper(char?opThis,int?prec1){

????????while(!s1.isEmpty()){

????????????char?opTop = s1.pop();

????????????if(opTop ==?'('){//如果棧頂是'(',直接將操作符壓入s1

????????????????s1.push(opTop);

????????????????break;

????????????}else{

????????????????int?prec2;

????????????????if(opTop ==?'+'?|| opTop ==?'-'){

????????????????????prec2 =?1;

????????????????}else{

????????????????????prec2 =?2;

????????????????}

????????????????if(prec2 < prec1){//如果當前運算符比s1棧頂運算符優先級高,則將運算符壓入s1

????????????????????s1.push(opTop);

????????????????????break;

????????????????}else{//如果當前運算符與棧頂運算符相同或者小于優先級別,那么將S1棧頂的運算符彈出并壓入到S2中

????????????????????//并且要再次再次轉到while循環中與 s1 中新的棧頂運算符相比較;

????????????????????s2.push(opTop);

????????????????}

????????????}

?????????????

????????}//end while

????????//如果s1為空,則直接將當前解析的運算符壓入s1

????????s1.push(opThis);

????}

?????

????//當前字符是 ')' 時,如果棧頂是'(',則將這一對括號丟棄,否則依次彈出s1棧頂的字符,壓入s2,直到遇到'('

????public?void?gotParen(char?ch){

????????while(!s1.isEmpty()){

????????????char?chx = s1.pop();

????????????if(chx ==?'('){

????????????????break;

????????????}else{

????????????????s2.push(chx);

????????????}

????????}

????}

?

}

  三、測試

1

2

3

4

5

6

7

8

9

10

@Test

public?void?testInfixToSuffix(){

????String input;

????System.out.println("Enter infix:");

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

????input = scanner.nextLine();

????InfixToSuffix in =?new?InfixToSuffix(input);

????MyCharStack my = in.doTrans();

????my.displayStack();

}

  四、結果

  

?  五、分析

  

?

  ②、計算機如何實現后綴表達式的運算?

  

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

package?com.ys.poland;

?

public?class?CalSuffix {

????private?MyIntStack stack;

????private?String input;

?????

????public?CalSuffix(String input){

????????this.input = input;

????????stack =?new?MyIntStack(input.length());

?????????

????}

?????

????public?int?doCalc(){

????????int?num1,num2,result;

????????for(int?i =?0?; i < input.length() ; i++){

????????????char?c = input.charAt(i);

????????????if(c >=?'0'?&& c <=?'9'){

????????????????stack.push((int)(c-'0'));//如果是數字,直接壓入棧中

????????????}else{

????????????????num2 = stack.pop();//注意先出來的為第二個操作數

????????????????num1 = stack.pop();

????????????????switch?(c) {

????????????????case?'+':

????????????????????result = num1+num2;

????????????????????break;

????????????????case?'-':

????????????????????result = num1-num2;

????????????????????break;

????????????????case?'*':

????????????????????result = num1*num2;

????????????????????break;

????????????????case?'/':

????????????????????result = num1/num2;

????????????????????break;

????????????????default:

????????????????????result =?0;

????????????????????break;

????????????????}//end switch

?????????????????

????????????????stack.push(result);

????????????}//end else

????????}//end for

????????result = stack.pop();

????????return?result;

????}

?????

????public?static?void?main(String[] args) {

????????//中綴表達式:1*(2+3)-5/(2+3) = 4

????????//后綴表達式:123+*123+/-

????????CalSuffix cs =?new?CalSuffix("123+*523+/-");

????????System.out.println(cs.doCalc());?//4

????}

?

}

  

回到頂部

4、前綴表達式

  前綴表達式,指的是不包含括號,運算符放在兩個運算對象的前面,嚴格從右向左進行(不再考慮運算符的優先規則),所有的計算按運算符出現的順序。

  注意:后綴表達式是從左向右解析,而前綴表達式是從右向左解析。

  ①、如何將中綴表達式轉換為前綴表達式?

  

?

  ②、計算機如何實現前綴表達式的運算?

  

?

  

參考文檔:http://blog.csdn.net/antineutrino/article/details/6763722/  

參考書籍:《Java數據結構和算法》  

作者:YSOcean

出處:http://www.cnblogs.com/ysocean/

?

  四、結果

  

?  五、分析

  

?

?

  ②、計算機如何實現后綴表達式的運算?

  

+ View Code

  

回到頂部

4、前綴表達式

  前綴表達式,指的是不包含括號,運算符放在兩個運算對象的前面,嚴格從右向左進行(不再考慮運算符的優先規則),所有的計算按運算符出現的順序。

  注意:后綴表達式是從左向右解析,而前綴表達式是從右向左解析。

?

  ①、如何將中綴表達式轉換為前綴表達式?

  

?

?

  ②、計算機如何實現前綴表達式的運算?

  

?

  

參考文檔:http://blog.csdn.net/antineutrino/article/details/6763722/  

參考書籍:《Java數據結構和算法》  

作者:YSOcean

出處:http://www.cnblogs.com/ysocean/

總結

以上是生活随笔為你收集整理的Java数据结构和算法(六)——前缀、中缀、后缀表达式的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。