2010年12月19日 星期日

高中 d016. 後序運算法



想看題目請點我

#include<iostream>
using namespace std ;

int operation(int temp1,int temp2,char op) ; // 計算 
int push(int temp1) ; // 放入 
int pop(int temp1) ; // 取出 

#define strLen 200 // 定義能讀取字元的數目 
char str[strLen] ;
int stack[strLen] ;
int stackLen = 0 ;
int main()
{
    while(cin.getline(str,50)) // 輸入 str 字串, 最多 strLen 個字元 (getline : 讀取整行)
    {
        int result = 0 ;
        for(int i = 0 ; i < strlen(str) ; i++) 
        {
            if(!isspace(str[i])) // 當 str[i] 不是空白才執行 
            { 
                if((int)str[i] >= 48 && (int)str[i] <= 57) // 取 0~9 數字 ascii
                {
                    push(((int)str[i])-48) ;
                }
                else // 若是運算元則執行
                {
                    result = operation(pop(stackLen-1),pop(stackLen-1),str[i]) ;
                    stack[stackLen] = result ; // 處理須放入堆疊在運算的一類 ex 20 30 + 40 *  
                }
            }
            else
            {
                stackLen++ ; // 當是空白時 代表要放入下一個數字 
            }
        }
        stack[stackLen] = 0 ; //清除最後存的 result 
        cout << result << endl ;
    } 
}

int operation(int temp1,int temp2,char op)
{
    switch(op)
    {
        case '+':
             return temp1+temp2;
        case '-':
             return temp1-temp2;
        case '*':
             return temp1*temp2;
        case '/':
             return temp1/temp2;
        case '%':
             return temp1%temp2;
    }
}

int push(int temp1) // 放入 
{
    stack[stackLen] = stack[stackLen]*10 + temp1 ;
}

int pop(int temp1) // 取出 
{ 
    int returnNumber = stack[temp1] ;
    stackLen-- ;
    stack[stackLen] = 0; //清除
    return returnNumber ;
}

這題大概說明一下小弟的想法 ,
push(((int)str[i])-48)這一段呢 ,

會去做 stack[stackLen] = stack[stackLen]*10 + temp1 ,
為什麼要這樣做呢 ?
因為電腦只會由左往右看 ,
但是很不巧的左邊又是比較大的數目 ,
因此每當向右移動一格時 左邊就多10倍 ,
ex:
    543
step1 : 5
step2 : 5 * 10 + 4 = 54
step3 : 54 * 10 + 3 = 543

還有一個小弟想的小技巧 ,
關於stackLen++與stackLen--的時機 ,
ex:
   3 5 +
step1 : strack[0] = 3
step2 : 遇到空白 , stackLen++
step3 : strack[1] = 5
step4 : 遇到空白 , stackLen++
step5 : strack[2] = + ,

在這時會去做operation(pop(stackLen-1),pop(stackLen-1),str[i]) ,
這行會因為pop而stackLen--做兩次 ,
所以最後回傳時 strack[0] = (3+5) 的答案

附註:operation(pop(stackLen-1),pop(stackLen-1),str[i])
    這行應該由左向右執行 ,
    因此會先做左邊的pop(stackLen-1)