帶括號的表示式計算(字尾表示式實現)
阿新 • • 發佈:2019-02-14
從標準輸入中讀入一個整數算術運算表示式,如24 / ( 1 + 2 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 )= ,計算表示式結果,並輸出。
要求:
1、表示式運算子只有+、-、*、/,表示式末尾的=字元表示表示式輸入結束,表示式中可能會出現空格;
2、表示式中會出現圓括號,括號可能巢狀,不會出現錯誤的表示式;
3、出現除號/時,以整數相除進行運算,結果仍為整數,例如:5/3結果應為1。
4、要求採用逆波蘭表示式來實現表示式計算。
【輸入形式】
從鍵盤輸入一個以=結尾的整數算術運算表示式。操作符和運算元之間可以有空格分隔。
【輸出形式】
在螢幕上輸出計算結果(為整數,即在計算過程中除法為整除)。
【樣例輸入】
24 / ( 1 + 2 + 36 / 6 / 2 - 2) * ( 12 / 2 / 2 ) =
【樣例輸出】
18
【樣例說明】
按照運算子及括號優先順序依次計算表示式的值。
思路和方法在註釋當中寫有哦~
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<ctype.h> int main() { int top_post = -1, top_stack = -1; //top_post表示指向字尾表示式的 “指標”, top_stack 表示指向棧的 “指標” char postfix[100] = "0"; //存放字尾表示式的陣列,後面的cal_stack 才是真正用來運算的棧 char stack[100] = "0"; //存放運算子號的棧 int num_stack[100] = {0}; char num[32] = {0} ; /*temporarily store the char that is number and turn them into integer遇到是數字的字元後期轉化為int型*/ int m = 0, number = 0, k; char tmp; /*turn it into postfix expression*/ while(1) { scanf("%c", &tmp); if(tmp == '=') break; /*遇到等號則式子輸入結束,退出迴圈*/ else if( isdigit(tmp) ) /*如果發現tmp是數字,則往下get a complete integer讀入完整整數*/ { m = 0; while( isdigit(tmp) ) { num[m++] = tmp; /*從0開始存,然後在 + 1 ,存到下一個下標*/ scanf("%c", &tmp); } ungetc(tmp, stdin); //最後會多讀一個不是digit的字元,退回 num[m] = '\0'; number = atoi(num); //會得到該完整整數的字串 postfix[++top_post] = 'n'; /*由於數字都混在一起難以分辨,這裡用n 替代一個數字的位置,put sth as substitue of number*/ num_stack[top_post] = number; /*數字棧中的number 和postfix當中的n位置是一一對應的,number stack sync with postfix*/ memset(num, 0, sizeof(num)); /*清空num 陣列以便下一輪使用*/ } else if( isspace(tmp) ) continue; else if( tmp == '*' || tmp == '/' ) /*若發現乘除運算,優先級別高,則先把所有緊隨其後的乘除運算出棧弄掉,放到字尾表示式裡*/ { while( stack[top_stack] == '*' || stack[top_stack] == '/' ) { postfix[++top_post] = stack[top_stack]; top_stack--; } stack[++top_stack] = tmp; } else if(tmp == '+' ||tmp == '-' ) { while( stack[top_stack] == '*' || stack[top_stack] == '/' ) { postfix[++top_post] = stack[top_stack]; top_stack--; } stack[++top_stack] = tmp; } else if(tmp=='(') { stack[++top_stack] = tmp; } else if(tmp == ')') { while( stack[top_stack] != '(' ) //遇到右括號,一直出棧至找到左括號 { postfix[++top_post] = stack[top_stack]; top_stack--; } top_stack--; /*然後出棧刪除掉左括號delete the left bracket*/ stack[top_stack+1] = '\0'; } } /*after read the equal '=' */ while( top_stack > -1 ) { postfix[++top_post] = stack[top_stack]; top_stack--; } stack[++top_stack] = '\0'; postfix[++top_post] = '\0'; printf("%s\n", postfix); //可以檢視字尾表示式,其中的 n 就是對應的數字 /*now the top_stack should be -1;*/ /*下面根據字尾表示式開始計算 calculate the postfix expression*/ int cal_stack[100]; int i = 0; int tmp_result; top_stack = -1; //此處top_stack 是指向 cal_stack 頂部的 “指標” while( postfix[i] != '\0' ) { if( postfix[i] == 'n' ) /*it is supposed to be a number 發現 n 表明讀到一個數字,讓數字入棧*/ { cal_stack[++top_stack] = num_stack[i]; /*現在處於表示式的第 i 個位置,在運算棧中放入num_stack 對應位置的真實數字*/ } else if( postfix[i] == '*' ) //讓前一個數字和當前數字 對該符號進行運算 並加到結果裡 { tmp_result = cal_stack[top_stack-1] * cal_stack[top_stack]; top_stack = top_stack - 2; //兩個已經參加運算的數字出棧 cal_stack[++top_stack] = tmp_result; //用該運算結果替代剛才運算的元素,如此往復 } else if(postfix[i] == '/') { tmp_result = cal_stack[top_stack-1] / cal_stack[top_stack]; top_stack = top_stack - 2; cal_stack[++top_stack] = tmp_result; } else if(postfix[i] == '+') { tmp_result = cal_stack[top_stack-1] + cal_stack[top_stack]; top_stack = top_stack - 2; cal_stack[++top_stack] = tmp_result; } else if(postfix[i] == '-') { tmp_result = cal_stack[top_stack-1] - cal_stack[top_stack]; top_stack = top_stack - 2; cal_stack[++top_stack] = tmp_result; } i++; } //最後可直接得到運算結果 printf("%d", tmp_result); return 0; }