/*本程序有点LOW,所以破事儿多,第一,输入各种符号只能用英文,特别是小括号,
只能在英文状态下才能正确,第二,输入的算式中,只能是一位整数,不能是两位,也不能是浮点数*/
#include<stdio.h>
#include<stdlib.h>
#define STACK_INIT_SIZE 100
#define STACKINCREMENT 10
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define INFEASIBLE -2
typedef struct
{
int *base;
int *top;
int stacksize;
}SqStack;
void SqStack_Init(SqStack &S)
{
S.base=(int *)malloc(STACK_INIT_SIZE*sizeof(int));//申请空间并判断是否成功
if(!S.base)
exit(INFEASIBLE);
S.top=S.base;//设置为空栈
S.stacksize=STACK_INIT_SIZE;//设置栈的大小
}//初始化栈
void SqStack_Push(SqStack &S,int Elem)
{
if(S.top-S.base>=S.stacksize)//判断时候超过当前的栈的大小
{
S.base=(int *)realloc(S.base,(STACK_INIT_SIZE+STACKINCREMENT)*sizeof(int));//重新申请空间并判断是否成功
if(!S.base)
exit(INFEASIBLE);
S.top=S.base+S.stacksize;//更改栈顶地址
S.stacksize+=STACKINCREMENT;//更改栈的大小
}
*S.top++=Elem;//赋值入栈
}//入栈
int SqStack_Pop(SqStack &S,int &Elem)
{
if(S.base==S.top)//判断是否为空栈
return ERROR;
Elem=*--S.top;//赋值返回
return OK;
}//出栈
int SqStack_Gettop(SqStack &S,int &Elem)
{
if(S.base==S.top)//判断是否为空栈
return ERROR;
Elem=*(S.top-1);//赋值返回
return OK;
}
int SqStack_Show(SqStack &S)
{
int *Base=S.base;//把栈底地址赋值给另外一个地址
if(S.base==S.top)//判断是否为空栈
return ERROR;
while(Base!=S.top)//当地址等于栈顶地址时结束遍历
{
printf("%d ",*Base);//输出
Base++;//地址移位
}
printf("\n");
return OK;
}//输出栈(本函数主程序中并没有用到,只是检测时候创建栈成功)
int Bracket_Match(char expression[])
{
int i,State,Elem;
SqStack S;
SqStack_Init(S);//初始化栈
for(i=0;expression[i]!='\0';i++)
{
switch(expression[i])
{
case '(':
case '[':
case '{':
SqStack_Push(S,expression[i]);//当括号为左括号时,入栈
break;
case ')':
State=SqStack_Pop(S,Elem);
if(State==ERROR||Elem!=(int)'(')
return ERROR;//当右括号为)时,判断栈顶是否匹配或为空,匹配则出栈,否则报错
break;
case ']':
State=SqStack_Pop(S,Elem);
if(State==ERROR||Elem!=(int)'[')
return ERROR;//当右括号为]时,判断栈顶是否匹配或为空,匹配则出栈,否则报错
break;
case '}':
State=SqStack_Pop(S,Elem);
if(State==ERROR||Elem!=(int)'{')
return ERROR;//当右括号为}时,判断栈顶是否匹配或为空,匹配则出栈,否则报错
break;
}
}
State=SqStack_Gettop(S,Elem);//当算式遍历完后,判断栈时候为空,不为空,则报错
if(State==ERROR)
return OK;
return ERROR;
}//括号匹配(检测算式的括号部分是否正确)
int Expression_Check(char expression[])
{
int i,flag1,flag2;
for(i=1;expression[i]!='\0';i++)
{
switch(expression[i-1])
{
case '+':
case '-':
case '*':
case '/':
case '(':
flag1=1;
break;//当前字符的前一个字符
default:
flag1=0;
}
switch(expression[i])
{
case '+':
case '-':
case '*':
case '/':
case ')':
flag2=1;
break;//当前字符
default:
flag2=0;
}
if(flag1*flag2)//如果上述的两种情况同时满足,则算式错误
return ERROR;
}
switch(expression[i-1])
{
case '+':
case '-':
case '*':
case '/':
case '(':
return ERROR;
}
return OK;//算式最后一位不能为以上字符
}//算式数字与运算符是否正确的检查
int Mid_Rear(char Mid[],char Rear[])
{
int State,i,j=0,Elem;
SqStack S;
SqStack_Init(S);
State=Expression_Check(Mid);//检查算式是否错误
if(State==ERROR)
return ERROR;
for(i=0;Mid[i]!='\0';i++)//组个遍历算式的字符
{
switch(Mid[i])
{
case '+':
case '-':
/*
当字符为+、-字符时,将栈中元素出栈,直至空栈或者栈顶为(,入栈
*/
State=SqStack_Gettop(S,Elem);
while(State!=ERROR&&Elem!=(int)'(')
{
Rear[j++]=Elem;//将中缀串赋给后缀串
State=SqStack_Pop(S,Elem);
State=SqStack_Gettop(S,Elem);
}
SqStack_Push(S,(int)Mid[i]);
break;
case '*':
case '/':
/*当字符为*、/字符时,将栈中元素出栈,直至栈空,或者遇到+、-、(字符,入栈
*/
State=SqStack_Gettop(S,Elem);
while(State!=ERROR&&Elem!=(int)'('&&Elem!=(int)'+'&&Elem!=(int)'-')
{
Rear[j++]=Elem;//将中缀串赋给后缀串
State=SqStack_Pop(S,Elem);
State=SqStack_Gettop(S,Elem);
}
SqStack_Push(S,(int)Mid[i]);
break;
case '(':
SqStack_Push(S,(int)Mid[i]);//字符(直接入栈
break;
case ')':
State=SqStack_Pop(S,Elem);
while(State!=ERROR&&Elem!=(int)'(')
{
Rear[j++]=Elem;
State=SqStack_Pop(S,Elem);
}
if(State==ERROR)
return ERROR;
break;//当字符为)时,将栈中元素出栈,直至(或者空栈,空栈报错
default:
Rear[j++]=Mid[i];//当为数字字符时,直接转为后缀
}
}
State=SqStack_Pop(S,Elem);
while(State!=ERROR&&Elem!=(int)'(')
{
Rear[j++]=Elem;
State=SqStack_Pop(S,Elem);
}//遍历完后,依次将栈中元素出栈,赋值给后缀串,当栈中纯在(字符时,报错
if(Elem==(int)'(')
return ERROR;
Rear[j]='\0';
return OK;
}//中缀字符串转后缀字符串
void Caculation(char Rear[],int &Result)
{
int i,State,Elem1,Elem2;
SqStack S;
SqStack_Init(S);
for(i=0;Rear[i]!='\0';i++)//逐个遍历后缀
{
switch(Rear[i])
{
case '+'://直接将栈顶两个元素出栈后相加后入栈
State=SqStack_Pop(S,Elem1);
State=SqStack_Pop(S,Elem2);
Elem1=Elem2+Elem1;
SqStack_Push(S,Elem1);
break;
case '-'://直接将栈顶两个元素出栈后相减后入栈
State=SqStack_Pop(S,Elem1);
State=SqStack_Pop(S,Elem2);
Elem1=Elem2-Elem1;
SqStack_Push(S,Elem1);
break;
case '*'://直接将栈顶两个元素出栈后相乘后入栈
State=SqStack_Pop(S,Elem1);
State=SqStack_Pop(S,Elem2);
Elem1=Elem2*Elem1;
SqStack_Push(S,Elem1);
break;
case '/'://直接将栈顶两个元素出栈后相除后入栈
State=SqStack_Pop(S,Elem1);
State=SqStack_Pop(S,Elem2);
Elem1=Elem2/Elem1;
SqStack_Push(S,Elem1);
break;
default:
SqStack_Push(S,Rear[i]-'0');//数字直接入栈
}
}
State=SqStack_Pop(S,Elem1);//将栈中的最后一个元素出栈,并且返回(计算结果)
Result=Elem1;
}//计算后缀表达式
int main()
{
int State,Result;
char Mid[256],Rear[256];
while(1)
{
system("cls");
printf("现阶段由于程序比较LOW,请按注意事项输入:\n1.所有输入均是在英文状态下输入\n2.输入时数字仅限一位整数进行运算\n");
printf("请输入中缀:");
gets(Mid);
State=Mid_Rear(Mid,Rear);
if(State==ERROR)
printf("表达式错误!\n");
else
{
printf("表达式正确!\n");
printf("后缀:%s\n",Rear);
Caculation(Rear,Result);
printf("结果:%d\n",Result);
}
system("pause");
}
return 0;
}
数据结构(C++) 栈-括号匹配与中缀转后缀
最新推荐文章于 2023-11-26 22:02:42 发布