用棧實現的整型數據的四則運算


只是簡單的整型數據的四則運算,小伙伴們可以擴展到更多的運算,也不僅僅是整型數據O(∩_∩)O~,我經常把抽象數據類型的全部操作都包括進來,顯得程序比較冗余,小伙伴們可以將不需要的操作去掉!而且要實現程序能夠運行出來,要注意把需要的頭文件包含進來

頭文件:

#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define MYOVERFLOW -2
typedef int Status;
typedef char SElemtype;//用指定標識符Elemtype代表int類型,顧名思義表示元素類型為int型
typedef struct{
    SElemtype *base;//在棧構造之前和銷毀之后,base的值為NULL
    SElemtype *top;//棧頂!d=====( ̄▽ ̄*)b指針
    int stacksize;//當前已分配的空間儲存,以元素為單位
}SqStack;
typedef int SElemtype1;//用指定標識符Elemtype代表int類型,顧名思義表示元素類型為int型
typedef struct{
    SElemtype1 *base;//在棧構造之前和銷毀之后,base的值為NULL
    SElemtype1 *top;//棧頂!d=====( ̄▽ ̄*)b指針
    int stacksize;//當前已分配的空間儲存,以元素為單位
}SqStack1;
Status InitStack(SqStack1 &S);//構造一個空棧S
Status GetTop(SqStack1 S, SElemtype1 &e);//若棧不空,則用e返回S的棧頂元素,並返回OK;否則返回ERROR
Status Push(SqStack1 &S, SElemtype1 e);//插入元素e為新的棧頂元素
Status Pop(SqStack1 &S, SElemtype1 &e);//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
//-------上述操作屬於函數的重載--------


//-------基本操作的函數原型說明--------
Status visit(SqStack S);//對棧進行遍歷
void Create_Stack(SqStack &S);//創建一個棧
Status InitStack(SqStack &S);//構造一個空棧S
Status DestroyStack(SqStack &S);//銷毀棧S,S不再存在
Status ClearStack(SqStack &S);//把S置為空棧
Status StackEmpty(SqStack S);//若棧S為空棧,則返回TRUE,否則返回FALSE    
int StackLength(SqStack S);//返回S的元素個數,即棧的長度
Status GetTop(SqStack S, SElemtype &e);
//若棧不空,則用e返回S的棧頂元素,並返回OK;否則返回ERROR
Status Push(SqStack &S, SElemtype e);
//插入元素e為新的棧頂元素
Status Pop(SqStack &S, SElemtype &e);
//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
Status StackTraverse(SqStack S, Status(*visit)(SqStack S));
//從棧底到棧頂依次對棧中每個元素調用函數visit()一旦visit()失敗,則操作失敗
int EvaluateExpression();
//算術表達式求值的算符優先算法。設OPTR和OPND分別為運算符棧和運算數棧,
//OP為運算符集合。

上述操作的實現:

#include "stdafx.h"
Status InitStack(SqStack &S)//構造一個空棧S
{
    S.base = (SElemtype *)malloc(STACK_INIT_SIZE*sizeof(SElemtype));
    if (!S.base)exit(MYOVERFLOW);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}
Status DestroyStack(SqStack &S)//銷毀棧S,S不再存在
{
    for (; S.top != S.base;){
        SElemtype *temp = S.top;
        S.top--;
        delete temp;
    }
    delete S.base;
    S.stacksize = 0;
    return OK;
}
Status ClearStack(SqStack &S)//把S置為空棧
{
    S.top = S.base;
    return OK;
}
Status StackEmpty(SqStack S)//若棧S為空棧,則返回TRUE,否則返回FALSE
{
    if (S.top == S.base)return TRUE;
    else return FALSE;
}
int StackLength(SqStack S)//返回S的元素個數,即棧的長度
{
    int length = 0;
    for (; S.top != S.base; S.top--)length++;
    return length;
}
Status GetTop(SqStack S, SElemtype &e)
//若棧不空,則用e返回S的棧頂元素,並返回OK;否則返回ERROR
{
    if (S.top != S.base){
        e = *(S.top - 1);
        return OK;
    }
    else return ERROR;

}
Status Push(SqStack &S, SElemtype e)
//插入元素e為新的棧頂元素
{
    if (S.top - S.base >= S.stacksize){
        S.base = (SElemtype *)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemtype));
        if (!S.base)exit(MYOVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *(S.top++) = e;
    return OK;
}
Status Pop(SqStack &S, SElemtype &e)
//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
{
    if (S.top != S.base){
        e = *(--S.top);
        return OK;
    }
    else return ERROR;
}
Status visit(SqStack S)//對棧進行遍歷1
{
    if (S.base){
        cout << "the data of the Stack is:";
        for (; S.top != S.base;)
            cout << *(--S.top) << " ";
        return OK;
    }
    else return ERROR;
}
Status StackTraverse(SqStack S, Status(*visit)(SqStack))
//從棧底到棧頂依次對棧中每個元素調用函數visit()一旦visit()失敗,則操作失敗
{
    if (visit(S))return OK;
    return ERROR;
}
void Create_Stack(SqStack &S)//創建一個棧
{
    InitStack(S);
    cout << "please input the length of the Stack:";
    int len;
    cin >> len;
    cout << "please input the data of the Stack:";
    for (int i = 1; i <= len; i++){
        SElemtype temp;
        cin >> temp;
        Push(S, temp);
    }
}
//------------接下來的幾個函數都是函數的重載---------------
//------------也可以用函數的模板,因為他們之---------------
//----------間僅有數據類型不同,實現過程完全相同-----------
Status InitStack(SqStack1 &S)//構造一個空棧S
{
    S.base = (SElemtype1 *)malloc(STACK_INIT_SIZE*sizeof(SElemtype1));
    if (!S.base)exit(MYOVERFLOW);
    S.top = S.base;
    S.stacksize = STACK_INIT_SIZE;
    return OK;
}
Status GetTop(SqStack1 S, SElemtype1 &e)//若棧不空,則用e返回S的棧頂元素,並返回OK;否則返回ERROR
{
    if (S.top != S.base){
        e = *(S.top - 1);
        return OK;
    }
    else return ERROR;

}
Status Push(SqStack1 &S, SElemtype1 e)//插入元素e為新的棧頂元素
{
    if (S.top - S.base >= S.stacksize){
        S.base = (SElemtype1 *)realloc(S.base, (S.stacksize + STACKINCREMENT)*sizeof(SElemtype1));
        if (!S.base)exit(MYOVERFLOW);
        S.top = S.base + S.stacksize;
        S.stacksize += STACKINCREMENT;
    }
    *(S.top++) = e;
    return OK;
}
Status Pop(SqStack1 &S, SElemtype1 &e)//若棧不空,則刪除S的棧頂元素,用e返回其值,並返回OK;否則返回ERROR
{
    if (S.top != S.base){
        e = *(--S.top);
        return OK;
    }
    else return ERROR;
}
Status In(char c, char *OP){//如果字符在數組中返回TRUE,否則返回FALSE
    for (int i = 0; i<=6;i++)
    if (c == OP[i])return TRUE;
    return FALSE;
}
char Precede(char ch, char c)//比較兩個字符的優先級
{
    int i=0, j=0;
    char mychar[][7] = { //定義一個二維字符數組
        { '>', '>', '<', '<', '<', '>', '>' },
        { '>', '>', '<', '<', '<', '>', '>' },
        { '>', '>', '>', '>', '<', '>', '>' },
        { '>', '>', '>', '>', '<', '>', '>' },
        { '<', '<', '<', '<', '<', '=', ' ' },
        { '>', '>', '>', '>', ' ', '>', '>' },
        { '<', '<', '<', '<', '<', ' ', '=' } };
    char OP[] = { '+', '-', '*', '/', '(', ')', '#' };
    for (; i <= 6;i++)
    if (ch == OP[i])break;
    for (; j <= 6;j++)
    if (c == OP[j])break;//得到兩字符在數組中的位置
    return mychar[i][j];//返回比較結果
}
int Operate(int a, char theta, int b){
    char OP[] = { '+', '-', '*', '/' };//比較是哪一個操作符
    int i = 0;
    for (; i <= 3;i++)
    if (theta == OP[i])break;
    switch (i)
    {
    case 0://操作符的位置為0則為+,下面類似
        return a + b;
    case 1:
        return a - b;
    case 2:
        return a*b;
    default:
        return a / b;
    }
}
int EvaluateExpression()
//算術表達式求值的算符優先算法。設OPTR和OPND分別為運算符棧和運算數棧,
//OP為運算符集合。
{
    cout << "please input the arithmetic and the end of it should be '#':" << endl;
    SqStack OPTR;//運算符棧
    SqStack1 OPND;//運算數棧
    InitStack(OPTR); Push(OPTR, '#');//這里用到了函數的重載,雖然都是對棧的操作,但操作數類型不同,
    InitStack(OPND);                 //運算符的數據元素為char,操作數的數據元素為int
    char c = getchar();char ch = ' ';
    char OP[] = { '+', '-', '*', '/', '(', ')', '#' };
    int temp = 0;
    bool tag = FALSE;
    do{
        if (!In(c, OP)){ temp = temp * 10 + c - 48; tag = TRUE;c = getchar(); }//如果對運算數的值進行了計算,則將tag設為TRUE
        else{                                                                  //說明如果后一個是運算符的話,可以將運算數壓入棧
            if (tag)
            {
                Push(OPND, temp); temp = 0; tag = FALSE;
            }
            GetTop(OPTR, ch);
            switch (Precede(ch, c)){
            case '<':
                Push(OPTR, c); c = getchar();//前個運算符小於后果運算符,則入棧
                break;
            case'=':
                char x;
                Pop(OPTR, x); c = getchar();//兩個運算符優先級相同,則出棧
                break;
            case'>':                         //前面一個運算符優先級高,則可進行計算
                char theta;
                Pop(OPTR, theta);
                int a, b;
                Pop(OPND, a); Pop(OPND, b);
                Push(OPND, Operate(b, theta, a));
                break;
            }
        }
    } while (c != '#');
    if (tag)Push(OPND, temp);//當遇到#時,還存在一次操作沒有進行,將該操作進行完全
    char theta;
    Pop(OPTR, theta);
    int a, b;
    Pop(OPND, a); Pop(OPND, b);
    Push(OPND, Operate(b, theta, a));
    int result;
    GetTop(OPND, result);
    cout << "the result of the arithmetic is:" << result << endl;
    return result;
}

主函數僅僅調用EvaluateExpression()函數,注意包含需要的頭文件!

下面是運算結果:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM