1. 程式人生 > >演算法練習——表示式計算

演算法練習——表示式計算

問題描述

  輸入一個只包含加減乖除和括號的合法表示式,求表示式的值。其中除表示整除。

輸入格式

  輸入一行,包含一個表示式。

輸出格式

  輸出這個表示式的值。

樣例輸入

1-2+3*(4-5)

樣例輸出

-4

資料規模和約定

表示式長度不超過100,表示式運算合法且運算過程都在int內進行。

C++程式碼如下:

#include<iostream>     
#include<cstring>     
#include<stack>     
#include<algorithm>  
#include<cmath>     
 
using namespace std;     
     
stack<char> s1,s2;     
stack<int> s3;     
char ch[150]={0};//用來存表示式     
int num[11];//用來暫時存數字     
           
int priority(char ch)//用於比較字元優先順序     
{     
   if(ch==')') return 1;     
   if(ch=='+'||ch=='-') return 2;     
   if(ch=='*'||ch=='/') return 3;     
   if(ch=='(') return 4;        
}     
          
int Scal(int x,int y,char ope)//兩個數的運算     
{     
   if(ope=='+') return x+y;     
   if(ope=='-') return x-y;      
   if(ope=='*') return x*y;     
   if(ope=='/'&&y!=0) return x/y;     
}     
     
void Transform(int n)//將中綴表示式轉化為字尾表示式     
{     
   int k=0;     
   for(int i=0;i<n;i++)     
   {     
       if(ch[i]>='0'&&ch[i]<='9')//當是數字的情況      
       {     
           if(i+1<n&&(ch[i+1]<'0'||ch[i+1]>'9')||i==n-1)//當是最後一個數字,或下一個元素是運算子     
           {     
                s2.push(ch[i]);     
                s2.push('#');     
           }     
           else     
                s2.push(ch[i]);     
       }     
       else     
       {     
           if(s1.empty()||ch[i]=='('||priority(ch[i])>priority(s1.top()))//當是運算子,有3種情況直接入棧     
                s1.push(ch[i]);                  
           else if(ch[i]==')')//當是右括號的情況     
           {     
                while(s1.top()!='(')     
                {     
                    s2.push(s1.top());       
                    s1.pop();     
                }     
                s1.pop();     
           }     
           else//當運算子優先順序小於或等於S1棧頂運算子的優先順序   
           {     
               while(!s1.empty()&&priority(ch[i])<=priority(s1.top())&&s1.top()!='(')//這裡還要注意兩個界限     
                {     
                    s2.push(s1.top());      
                    s1.pop();                
                }     
                s1.push(ch[i]);      
           }        
       }     
     
   }     
   while(!s1.empty())//當表示式結束     
   {     
       s2.push(s1.top());     
       s1.pop();            
   }     
   while(!s2.empty()) //將棧內元素放回S2中     
   {     
       ch[k++]=s2.top();     
       s2.pop();        
   }     
   reverse(ch,ch+k);//將ch[]反向     
   ch[k]=0;     
}     
     
int Cal(int n)//字尾表示式計算     
{     
   int x,y,tmp=0,k=0;     
   for(int i=0;i<n;i++)     
   {     
       if(ch[i]=='#')//是#直接跳過     
           continue;     
       else if(ch[i]=='+'||ch[i]=='-'||ch[i]=='*'||ch[i]=='/')//是運算子彈出棧頂兩元素計算後放回棧     
       {     
           x=s3.top();     
           s3.pop();     
           y=s3.top();     
           s3.pop();     
           x=Scal(y,x,ch[i]);     
           s3.push(x);     
       }     
       else//是數字字元     
       {     
           if(ch[i+1]=='#')//下一個元素是#     
           {     
                num[k++]=ch[i]-'0';     
                for(int i=0;i<k;i++)     
                   tmp+=(num[i]*(int)pow(10,k-i-1));     
                s3.push(tmp);     
               tmp=0;     
                k=0;                     
           }     
           else//下一個元素不是#     
           {     
                num[k++]=ch[i]-'0';      
           }        
       }     
   }     
   return s3.top();     
}     
     
int main()     
{     
   gets(ch);     
   Transform(strlen(ch));     
   cout<<Cal(strlen(ch))<<endl;     
   return 0;     
}