数据结构(C++) 栈-括号匹配与中缀转后缀

/*本程序有点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;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值