1. 程式人生 > >利用棧實現加減乘除冪功能

利用棧實現加減乘除冪功能

如何用棧來實現加減乘除冪的運算呢?應考慮下面幾點。

1.分別用一個棧x存符號,另一個棧y存數值。

2.遇到數字就壓棧,遇到符號ch要比較棧頂的符號與當前的符號ch,編寫一個判別函式prev,若能進行運算,則返回真,不能返回假.以下是判別函式的幾種情況:

(1)如果棧頂符號為* ^ / 則不用考慮輸入拿來比較的符號,直接返回真。

(2)如果棧頂符號和拿來比較的符號ch為+或者-,也返回真.

(3)其他遇到棧頂元素為括號或者棧頂符號為+or-,而ch為* / ^等等情況,直接返回假。

程式碼如下:

bool prev(char s1,char s2 ){                    //判斷符號s1 與 s2 的優先級別的函式
    if(s1=='^'||s1=='*'||s1=='/')                 //如果棧頂符號為* ^ / 則不用考慮輸入拿來比較的符號,直接返回真
        return true;
    else if((s1=='+'||s1=='-')&&(s2=='+'||s2=='-'))      //如果棧頂符號和拿來比較的符號為+或者-,也返回真
        return true;
        else
        return false;                                  //其他情況都返回假
    }

3.編寫計算函式result,並將計算結果壓入棧中,注意計算的是當前輸入符號ch前面的符號,計算完後要將當前符號ch壓入符號棧內。

void result(char ch,SeqStack<T> &s)                 //計算並將計算結果壓入棧中
{
    T x,y,result;
    x=s.Pop();
    y=s.Pop();
    switch(ch)
    {
        case '+':result=y+x;break;
        case '-':result=y-x;break;
        case '*':result=y*x;break;
        case '/':result=y/x;break;
        case '^':result=pow(y,x);break;
    }
    s.Push(result);
    return ;
}


具體程式碼如下:

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <assert.h>
#define Max 100
using namespace std;
bool prev(char s1,char s2 ){                    //判斷符號s1 與 s2 的優先級別的函式
    if(s1=='^'||s1=='*'||s1=='/')                 //如果棧頂符號為* ^ / 則不用考慮輸入拿來比較的符號,直接返回真
        return true;
    else if((s1=='+'||s1=='-')&&(s2=='+'||s2=='-'))//如果棧頂符號和拿來比較的符號為+或者-,也返回真
        return true;
        else
        return false;                                  //其他情況都返回假
    }

template <class T>
class SeqStack
{
public:
    SeqStack():top(-1){}
    ~SeqStack(){top=-1;}
    T Pop();
    T getTop();
    void Push(T x);
    bool IsEmpty();
    bool IsFull();
private:
    T A[Max];
    int top;
};
template <class T>
void result(char ch,SeqStack<T> &s)                 //計算並將計算結果壓入棧中
{
    T x,y,result;
    x=s.Pop();
    y=s.Pop();
    switch(ch)
    {
        case '+':result=y+x;break;
        case '-':result=y-x;break;
        case '*':result=y*x;break;
        case '/':result=y/x;break;
        case '^':result=pow(y,x);break;
    }
    s.Push(result);
    return ;
}
int main()
{
    SeqStack<char> x;                                           //符號棧
    SeqStack<double> y;                                       //數值棧
    char ch,c;
    double operand;
    x.Push('0');
    while(1)
    {
        cin.get(ch);
        if(ch=='+'||ch=='-'||ch=='*'||ch=='/')  //若是+-*/則要與符號棧棧頂元素比較,決定是否運算
        {
            c=x.getTop();             //c儲存當前棧頂值
           while(prev(c,ch))         //符號比較返回真,則要計算,迴圈直到棧內能計算的符號全部計算
            {
                result(c,y);            //注意計算時使用的是符號棧中棧頂符號
                x.Pop();                //彈出剛剛計算過的符號c
                c=x.getTop();           //c儲存當前符號棧棧頂的元素進行迴圈
            }
            x.Push(ch);                  //計算結束壓入剛剛輸入的符號
        }
        else if(ch=='^'||ch=='(')        //遇到符號^或者(直接壓棧,不用考慮比較符號和計算
            x.Push(ch);
        else if(ch==')')                 //遇到右括號,要對棧中元素進行迴圈計算,直到遇到左括號(
        {
            c=x.getTop();
            while(c!='(')                //此時的迴圈條件不是判斷符號,遇到符號就要計算,因為括號裡前面的元素,已經按優先順序計算好
            {
                result(c,y);
                x.Pop();
                c=x.getTop();
            }
            x.Pop();                        //彈出(符號
        }
        else if(isdigit(ch))                //是數字,放回輸入流,重新輸入數字,壓棧
        {
            cin.putback(ch);
            cin>>operand;
            y.Push(operand);

        }
        else if(ch=='\n')                  //遇到回車符,計算棧中仍未計算的數字,跳出迴圈
        {
            c=x.getTop();
            while(c!='0')
            {
                result(c,y);
                x.Pop();
                c=x.getTop();
            }
            cout<<y.Pop()<<endl;break;
        }
    }

    return 0;
}
template <class T>
T SeqStack<T>::Pop()
{
    assert(top!=-1);
    T x;
    x=A[top];
    top--;
    return x;
}
template <class T>
void SeqStack<T>::Push(T x)
{
    assert(top!=Max-1);
    top++;
    A[top]=x;
    return ;
}
template <class T>
T SeqStack<T>::getTop()
{
    assert(top!=-1);
    return A[top];
}
template <class T>
bool SeqStack<T>::IsEmpty()
{
    if(top==-1) return true;
    else return false ;
}
template <class T>
bool SeqStack<T>::IsFull()
{
    if(top==Max-1)return true;
    else return false;
}