1. 程式人生 > >帶括號的表示式計算(字尾表示式實現)

帶括號的表示式計算(字尾表示式實現)

從標準輸入中讀入一個整數算術運算表示式,如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;
    
}