只是簡單的整型數據的四則運算,小伙伴們可以擴展到更多的運算,也不僅僅是整型數據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()函數,注意包含需要的頭文件!
下面是運算結果: