C语言 栈的应用 计算简单的中缀表达式

代码简介:

下面的代码实现了计算简单的中缀表达式:只可以处理一位正整数的四则运算及括号。是栈的简单应用,要实现中缀表达式运算需要用两个栈,一个存储数字的栈和一个存储运算符的栈,因为懒得写两遍不同的栈上的操作,所以就用一个结构体实现了两个栈,用标志1表示操作其内部的栈1(int栈),标志2表示操作栈2(char栈),具体思路见代码。

完整代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXSIZE 100

typedef struct node *ptrNode;
typedef struct node
{
    int top1;
    int data1[MAXSIZE];

    int top2;
    char data2[MAXSIZE];
}stackNode;
typedef ptrNode stack_;

int empty_(stack_ st,int d)
{
    if(d==1 && st->top1 == -1)return 1;
    else if(d==2 && st->top2 == -1)return 1;
    return 0;
}
int full_(stack_ st,int d)
{
    if(d==1 && st->top1 == MAXSIZE-1)return 1;
    else if(d==2 && st->top2 == MAXSIZE-1)return 1;
    return 0;

}
void pop_(stack_ st,int d)
{
    if(d==1)
        st->top1--;
    else if(d==2)
        st->top2--;
}

void push_(stack_ st,int d,int data1,char data2)
{
    if(d==1)
        st->data1[++st->top1]=data1;
    else if(d==2)
        st->data2[++st->top2]=data2;
}
//显示栈顶
int top_num(stack_ st)
{
    return st->data1[st->top1];
}
char top_chr(stack_ st)
{
    return st->data2[st->top2];
}

stack_ init_stack()
{
    stack_ st = (stack_)malloc(sizeof(stack_) );
    st->top1  = -1;
    st->top2  = -1;
    return st;
}

int prior_chr(char c)
{
    if(c=='(')return 3;
    else if(strchr("*/",c))return 2;
    else if(strchr("+-",c))return 1;
}

int operate(char op,int a,int b)
{
    switch(op){
        case '+':return a+b;
        case '-':return a-b;
        case '*':return a*b;
        case '/':return a/b;
    }
}

int main()
{
    int out = 0;

    stack_ st = init_stack();
    char str[100];
    scanf("%s",&str);// \0结尾
    int don=0;

    while(str[don]!='\0')
    {
        if(str[don]-'0'>=0 && str[don]-'0'<10)//是数字,直接压栈
            push_(st,1,str[don]-'0','0');
        else if(str[don]==')')
        {   //一直出栈直到遇到左括号
            while( top_chr(st) != '(' )
            {
                char op = top_chr(st);
                pop_(st,2);
                int b   = top_num(st);
                pop_(st,1);
                int a   = top_num(st);
                pop_(st,1);
                out = operate(op,a,b);
                push_(st,1,out,'0');
            }
            pop_(st,2);//左括号出栈
        }
        else//是字符
        {
            int top_pro;
            if(!empty_(st,2))
                top_pro = prior_chr(top_chr(st));
            int now_pro = prior_chr(str[don]);

            if(empty_(st,2) || top_pro==3 ||top_pro<=now_pro)
                push_(st,2,0,str[don]);
            else //需要弹栈计算,暂时不压入
            {
                char op = top_chr(st);
                int b   = top_num(st);
                pop_(st,1);
                int a   = top_num(st);
                pop_(st,1);
                pop_(st,2);
                out = operate(op,a,b);
                push_(st,1,out,'0');
                don--;
            }
        }
        don++;
    }
    while(!empty_(st,2))
    {
        char op = top_chr(st);
        int b   = top_num(st);
        pop_(st,1);
        int a   = top_num(st);
        pop_(st,1);
        pop_(st,2);
        out = operate(op,a,b);
        push_(st,1,out,'0');
    }
    printf("out:%d\n",top_num(st));
    return 0;
}

代码解释:

如上,我图省事一个结构体放了两栈。

typedef struct node
{
int top1;
int data1[MAXSIZE];

int top2;
char data2[MAXSIZE];
}stackNode;

栈上有如下操作:

int empty_(stack_ st,int d) //判栈空,返回值为0表示栈非空,1表示栈空,参数 st表示该函数所操作的栈,参数d为1表示操作stack结构体中的int栈,2表示操作stack结构体中的char栈

int full_(stack_ st,int d) //判栈满,返回值为0表示栈非满,1表示栈满,参数含义与上相同

void push_(stack_ st,int d,int data1,char data2) //压数据入栈,参数st和d与上相同,data1表示待压入的int数据,data2表示待压入的char数据,由于d选择了操作哪一个栈,所以两个数据只有有效的那个会被压入,使用时不用的数据位随意填值就好(因为C语言没函数重载,写两个push又太麻烦所以就用这种方法了)

int top_num(stack_ st) //显示栈顶元素,该函数会返回int栈的栈顶元素
char top_chr(stack_ st)//显示栈顶元素,该函数会返回int栈的栈顶元素

另外说一下写这段代码我遇到的问题,需要注意的地方:一是在运算时(如下),需要获取两个数,在获取第一个数后需要弹栈,然后再获取第二个数(如代码第121行);

char op = top_chr(st);
int b = top_num(st);
pop_(st,1);
int a = top_num(st);
pop_(st,1);
pop_(st,2);
out = operate(op,a,b);
push_(st,1,out,'0');

二是在字符串处理完成后,还需要加个while循环处理栈,因为字符串处理完了但是栈中可能还存有数据没运算;三是代码第115行, top_pro==3 的意思是如果char栈的栈顶元素是(,那么不管是啥直接加进来就好了,这么处理的原因是当遇到(时,应该直接将其入栈,所以我给他设置了最高的优先级3(是唯一的,只有他有的优先级),而在其后要压操作入栈时,(后不管是啥都需要压入进来,所以这里特殊设置了一下,想不太明白的话自己写一个带括号的中缀表达式转换一下就好了。

if(empty_(st,2) || top_pro==3 ||top_pro<=now_pro)
push_(st,2,0,str[don]);

运行结果:

附几个运行结果。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值