棧的基本操作及應用
阿新 • • 發佈:2019-02-11
/*棧的基本操作及實現表示式求值*/
#include<stdio.h>
#include<stdlib.h>
#include<windows.h>
#define STACK_INIT_SIZE 100 //儲存空間初始分配量
#define STACKINCREMENT 10 //儲存空間分配增量
#define OK 1
#define OVERFLOW 0
#define ERROR 0
typedef int Status;
typedef struct {
float *base;//在棧構造之前和銷燬之後,base的值為NULL
float *top;//棧頂指標
int stacksize; //當前已分配的儲存空間
}SqStack;
char sign[8]={"+-*/()#"};
//運算子之間的關係
// + - * / ( ) #
char relation[7][7]={
/* + */{'>','>','<','<','<','>','>'},
/* - */{'>','>','<','<','<','>','>'},
/* * */ {'>','>','>','>','<','>','>'},
/* / */{'>','>','>','>','<','>','>'},
/* ( */{'<','<','<','<','<','=',' '},
/* ) */{'>','>','>','>',' ','>','>'},
/* # */{'<','<','<','<','<' ,' ','='}
};
//構造一個空棧S
Status InitStack(SqStack &S)
{
S.base = (float*)malloc(STACK_INIT_SIZE * sizeof(float));
if (!S.base)exit(OVERFLOW);//儲存分配失敗
S.top = S.base;
S.stacksize = STACK_INIT_SIZE;
return OK;
}
Status DestroyStack(SqStack &S)//銷燬棧
{
free(S.base);
S.stacksize=0;
S.top=S.base=NULL;
return OK;
}
Status ClearStack(SqStack &S)//清空棧
{
S.top=S.base;
return OK;
}
bool StackEmpty(SqStack &S)//判斷棧是否為空
{
if(S.top==S.base) return true;
return false;
}
//取棧頂元素
char GetTop(SqStack S)
{
if (S.top == S.base) return '#';
return char(*(S.top-1));
}
//插入元素e為新的棧頂元素
Status Push(SqStack &S, float e)
{
if (S.top - S.base >= S.stacksize)
{//棧滿,追加儲存空間
S.base = (float *)realloc(S.base, (S.stacksize + STACKINCREMENT) * sizeof(float));
if (!S.base) exit(OVERFLOW);//儲存分配失敗
S.top = S.base + STACKINCREMENT;
S.stacksize += STACKINCREMENT;
}
*S.top++ = e;
return OK;
}
//刪除S 的棧頂元素
float Pop(SqStack &S)
{
if(StackEmpty(S))return '#';
return *(--S.top);
}
char Precede(char a,char b)
{
int i,j;
switch(a)
{
case '+':i=0;break;
case '-':i=1;break;
case '*':i=2;break;
case '/':i=3;break;
case '(':i=4;break;
case ')':i=5;break;
case '#':i=6;break;
}
switch(b)
{
case '+':j=0;break;
case '-':j=1;break;
case '*':j=2;break;
case '/':j=3;break;
case '(':j=4;break;
case ')':j=5;break;
case '#':j=6;break;
}
return relation[i][j];
}
float Operate(float a,char opr,float b)//計算
{
if(opr=='+')return a+b;
else if(opr=='-')return a-b;
else if(opr=='*')return a*b;
else if(opr=='/')
{
if(b==0){printf("計算過程中出現了除數為0的情況!輸出結果錯誤!\n");system("pause");}
else return a/b;
}
}
bool is_OPND(char c)//判斷是否為數字
{
if((c>='0'&&c<='9' )||c=='.')return true;
return false;
}
void Getchar()
{
while(getchar()!='\n');
}
int main()
{
SqStack OPTR,OPND;
InitStack(OPTR);
InitStack(OPND);
Push(OPTR,float('#'));
char c;
printf("請輸入一個正確的算術表示式(用#號結束):\n");
scanf("%c",&c);
char num[20];
int Temp=1;
while(Temp)
{
while(c!='#'||GetTop(OPTR)!='#')
{
int i=0;
if(is_OPND(c))
{
num[i]=c;
while(scanf("%c",&c)&&(is_OPND(c)))
{
i++;num[i]=c;
}
float result=(float)atof(num);
Push(OPND,result);
}
else
{
switch(Precede(GetTop(OPTR),c))
{
case '<':Push(OPTR,c);scanf("%c",&c);break;
case '=':Pop(OPTR);scanf("%c",&c);break;
case '>':float b=Pop(OPND),a=Pop(OPND);
char opera=char(Pop(OPTR));
float f=Operate(a,opera,b);
Push(OPND,f);
}
}
memset(num,0,sizeof(num));
}
float output=Pop(OPND);
getchar();
printf("該算術表示式的值為:");
printf("%.2f\n",output);
printf("是否繼續計算表示式?(Y/N)");
char a=getchar(); Getchar();
if(a=='Y'||a=='y')
{
ClearStack(OPTR);
ClearStack(OPND) ;
printf("請輸入一個正確的算術表示式(用#結束):\n");
Push(OPTR,float('#'));
scanf("%c",&c);
}
else Temp=0;
}
DestroyStack(OPTR);
DestroyStack(OPND);
return 0;
}