1. 程式人生 > >資料結構棧實現四則運算

資料結構棧實現四則運算

例如,計算9+(3-1)*3+8/2

思路:通過棧來實現上述元素,我們一般稱上述表示式為中綴表示式,我們首先要將其轉換為字尾表示式,因為中綴表示式不利於計算機運算。

上程式碼:
演算法思路:
對字串中的內容,遇到數字就輸出,遇到符號則與棧頂元素比較優先順序,若低,則將棧頂元素彈棧,若高,則壓棧。若為右括號,則連續輸出,直到遇到左括號,這輸出的就是字尾表示式
其中isp()和icp()這兩個函式是對於優先順序的規定,在下一段程式碼中有它們的定義

void postfix(){
    stack<char> s;
    char y;
   // s.makeEmpty();
s.push('#'); char ch[20]="9+(3-1)*3+8/2"; for(int i=0;i<13;i++){ if(isdigit(ch[i])) cout<<ch[i]; else if(ch[i]==')'){ // cout<<ch[i]<<endl; while(!(s.empty())&&(y=s.top())!='('){ cout<<y; s.pop(); } if
(!s.empty()) s.pop(); } else{ while(!s.empty()&&isp(y=s.top())>icp(ch[i])){ cout<<y; s.pop(); } s.push(ch[i]); } } while(!s.empty()){ cout<<s.top(); s.pop(); } }

有了字尾表示式,我們需要的是計算,我們做的是,遇數字壓棧,與符號則彈出前兩個數進行計算,將結果入棧。

#include<cmath>
#include<stack>
#include<iostream>
using namespace std;
int isp(char ch){
    switch(ch){
        case '#':
            return 0;
        case '(':
            return 1;
        case '^':
            return 7;
        case '*':
        case '/':
        case '%':
            return 5;
        case '+':
        case '-':
            return 3;
        case ')':
            return 8;
    }
}
int icp(char ch){
    switch(ch){
        case '#':
            return 0;
        case '(':
            return 8;
        case '^':
            return 6;
        case '*':
        case '/':
        case '%':
            return 4;
        case '+':
        case '-':
            return 3;
        case ')':
            return 1;
    }
}

class Calculator{
public:
    Calculator(){}
    double Run();
    void Clear();
private:
    void AddOperand(double value);
    bool Get2Operands(double &left,double &right);
    void DoOperator(char op);
    stack<double> s;
};
void Calculator::AddOperand(double value){
    s.push(value);
}
void Calculator::Clear(){

}
bool Calculator::Get2Operands(double &left,double &right){
    if(s.empty()){
        cerr<<"Missing Operands!"<<endl;
        return false;
    }
    right = s.top();
    s.pop();
    if(s.empty()){
        cerr<<"Missing Operands!"<<endl;
        return false;
    }
    left = s.top();
    s.pop();
    return true;
}
void Calculator::DoOperator(char op){
    double left,right;
    bool result;
    result = Get2Operands(left,right);
    if(result==true){
        switch(op){
            case '+':
                s.push(left+right);
                break;
            case '-':
                s.push(left-right);
                break;
            case '*':
                s.push(left*right);
                break;
            case '/':
                if(abs(right)<=1E-6){
                    cerr<<"Divide By 0"<<endl;
                    Clear();
                }
                else
                    s.push(left/right);
                break;
         /*   case '^':
                s.push(left^right);
                break;*/
        }
    }
    else{
        Clear();
    }
}
double Calculator::Run(){
    char ch;
    double newoperand,ret;
    while(cin>>ch,ch!='='){
        switch( ch ) {
          case '+':
          case '-':
          case '*':
          case '/':
          case '^':
              DoOperator(ch);
              break;
          default:
              cin.putback(ch);
              cin >> newoperand;
              AddOperand(newoperand);
              break;
        }
    }
    ret = s.top();
    s.pop();
    return ret;
}

int main(){

   // postfix();
   Calculator c;
   double ans = c.Run();
   cout<<ans;
    return 0;
}