中綴表達式求值


描述

人們熟悉的四則運算表達式稱為中綴表達式,例如(23+34*45/(5+6+7))。在程序設計語言中,可以利用堆棧的方法把中綴表達式轉換成保值的后綴表達式(又稱逆波蘭表示法),並最終變為計算機可以直接執行的指令,得到表達式的值。
給定一個中綴表達式,編寫程序,利用堆棧的方法,計算表達式的值。

輸入

第一行為測試數據的組數N
接下來的N行,每行是一個中綴表達式。表達式中只含數字、四則運算符和圓括號,操作數都是正整數,數和運算符、括號之間沒有空格。中綴表達式的字符串長度不超過600。

輸出

對每一組測試數據輸出一行,為表達式的值

解法

該問題可以轉換為兩個子問題:

1、將中綴表達式轉換為后綴表達式

2、利用棧對后綴表達式求值

中綴表達式轉后綴表達式

算法: 可以使用棧來完成中綴表達式到后綴表達式的轉換

1、棧stack[]用來存儲操作符,top指向棧頂,但不存儲元素,top=0表示棧為空

2、從左向右遍歷中綴表達式

  a.如果遇到的是操作數num,則直接輸出到后綴表達式

  b.如果遇到的是操作符op,則有幾種情況:

    b.1.如果op==')',則依次彈出棧頂直到彈出'(',但'('不輸出到后綴表達式

    b.2:如果op=='(',則直接入棧

    b.3:如果棧為空,則直接入棧

    b.4:如果op的優先級高於棧頂操作符的優先級,則入棧

    b.5:如果op的優先級低於或等於棧頂操作符的優先級,則依次彈出棧頂直到op的優先級高於棧頂操作符的優先級(或棧為空),再將op入棧

3、遍歷完時,如果棧仍不為空,則依次彈出棧頂直到棧為空

具體的代碼如下:

 1 int mycmp(char a, char b) {
 2     if(b == '(')
 3         return 1;//左括號直接入棧
 4     else if((b == '*' || b == '/') &&(a == '+' || a == '-' || a == '('))
 5         return 1;//*、/優先級高於+、-、(,入棧
 6     else if((b == '+' || b == '-') && (a == '('))
 7         return 1;//+、-優先級高於(,入棧
 8     else
 9         return 0;
10 }
11 
12 /*中綴表達式轉后綴表達式
13  中綴表達式之間無分割
14  后綴表達式操作數、操作符之間用空格分割,便於區分不同操作數*/
15 void infix_to_suffix(char* infix, char* suffix) {
16     int i, k, j=0, top=0;
17     char stack[1000];//存儲運算符的棧
18 
19     for(i=0; infix[i]!='\0'; i++) {
20         if(infix[i] >= '0' && infix[i] <= '9') {
21             suffix[j++] = infix[i];//操作數則直接輸出
22         } else {
23             if(i != 0 && infix[i-1] >= '0' && infix[i-1] <= '9') {
24                 suffix[j++] = ' ';//操作數后補充空格分割
25             }
26             if(infix[i] == ')') {
27                 //遇到右括號則一直彈出直到左括號,但左括號不輸出
28                 while(stack[top-1] != '(') {
29                     suffix[j++] = stack[--top];
30                     suffix[j++] = ' ';
31                 }
32                 top--;
33             } else if(top == 0 || mycmp(stack[top-1], infix[i])) {
34                 //棧為空或當前操作符的優先級高於棧頂操作符,當前操作符入棧
35                 stack[top++] = infix[i];
36             } else {
37                 //當前操作符優先級等於或低於棧頂操作符則彈出棧頂
38                 while(!mycmp(stack[top-1], infix[i])) {
39                     suffix[j++] = stack[--top];
40                     suffix[j++] = ' ';
41                     if(top == 0)
42                         break;
43                 }
44                 stack[top++] = infix[i];//當前操作符入棧
45             }
46         }
47     }
48     //補充空格分割
49     if(suffix[j-1] != ' ') {
50         suffix[j++] = ' ';
51     }
52     //如果操作符棧不為空,彈出所有操作符
53     while(top != 0) {
54         suffix[j++] = stack[--top];
55         suffix[j++] = ' ';
56     }
57     suffix[j] = '\0';
58 }

 

利用棧對后綴表達式求值

算法:

1、棧stack[]用來存儲操作數,top指向棧頂,但不存儲元素,top=0表示棧為空,

2、從左向右依次遍歷后綴表達式

   a.如果遇到的是操作數num,則直接將num入棧,即stack[top++]=num

   b.如果遇到的是操作符op,則取出依次取出棧頂的兩個元素stack[top-2]和stack[top-1],計算stack[top-2] op stack[top-1]的結果,並將結果入棧

3、遍歷結束時,stack[top-1]即為后綴表達式求值結果

具體的C語言代碼如下:

 1 /*后綴表達式求值*/
 2 int suffix_value(char* suffix) {
 3     int i, j;
 4     char op;
 5     int stack[1000];
 6     int top = 0, value = 0;
 7     for(i=0; suffix[i] != '\0'; i++) {
 8         if(suffix[i] >= '0' && suffix[i] <= '9') {
 9             value = value*10 + suffix[i] - '0';
10         } else if(suffix[i] == ' ') {
11             //操作數入棧
12             stack[top++] = value;
13             value = 0;
14         } else {
15             //根據操作符,對棧頂兩個操作數進行計算並得到結果
16             switch(suffix[i]) {
17                 case '+': value = stack[top-2] + stack[top-1];break;
18                 case '-': value = stack[top-2] - stack[top-1];break;
19                 case '*': value = stack[top-2] * stack[top-1];break;
20                 case '/': value = stack[top-2] / stack[top-1];break;
21                 default: break;
22             }
23             top -= 2;
24         }
25     }
26 
27     return stack[0];
28 }

 

至此,中綴表達式求值的主程序如下:

 1 int main() {
 2     int n;
 3     char infix[1000], suffix[1000];//infix中綴表達式,suffix后綴表達式
 4     
 5     scanf("%d\n", &n);
 6     while(n--) {
 7         gets(infix);
 8         infix_to_suffix(infix, suffix);    
 9         printf("%d\n", suffix_value(suffix));
10     }
11 
12     return 0;
13 }

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM