C/C++:栈的应用:表达式求值

/**
*
* Author:HackerHao
* Create:2023.09.27
*
*/
#include <bits/stdc++.h>
using namespace std;
#define ElemType int
#define MAXSIZE 200
typedef struct
{
    ElemType data[MAXSIZE];   //数据域
    int top;   //栈顶"指针"
}SqStack;

SqStack* Create(void)  //创建栈,将top初始化为-1
{
    SqStack* k = (SqStack*)malloc(sizeof(SqStack));
    k->top = -1;
    return(k);
}

bool Push(SqStack* p, ElemType n)  //进栈
{
    //进栈先判断栈满!!!
    if (p->top == MAXSIZE - 1)
        return(false);
    p->data[++p->top] = n;
    return(true);
}

ElemType Pop(SqStack* p)  //出栈
{
    //出栈先判断栈空!!!
    if (p->top == -1)
        return(-1);    //返回-1表示出栈失败
    return(p->data[p->top--]);
}

ElemType Top(SqStack* p)   //获取栈顶元素
{
    //获取栈顶元素也要判断栈空!!!
    if (p->top == -1)
        return(-1); //返回-1表示取值失败
    return(p->data[p->top]); //直接返回栈顶元素
}

ElemType Expression(char* s)
{
    SqStack* Optr, * Oper;
    ElemType d, result;
    bool Calculate(SqStack * Oper, SqStack * Optr);
    Optr = Create();  //运算符栈
    Push(Optr, '#');    //字符#先压入栈中
    Oper = Create();        //操作数栈
    while (*s != '\0')
    {
        if (*s >= '0' && *s <= '9')
        {
            d = 0;
            while (*s >= '0' && *s <= '9') //用一个循环来计算连续的数字字符组成的值
            {
                d = 10 * d + *s - '0';
                s++;
            }
            s--;  //跳出循环,s指向数字字符的后面字符,为了同步,再--,否则将会跳过读取一个字符
            //将求的值压入Oper栈中
            Push(Oper, d);
        }
        else
        {
            if (*s == '(' || *s == '*' || *s == '/')
                Push(Optr, *s);    //乘和除优先级最高,(左括号,都直接进操作符栈
            else if (*s == ')')
            {
                while (Top(Optr) != '(')   //没到左括号,一直计算
                    Calculate(Oper, Optr);
                Pop(Optr);   //左括号出栈
            }
            else if (*s == '#')
            {
                while (Top(Optr) != '#')  //还剩有计算没做,继续运算
                    Calculate(Oper, Optr);
                break;
            }
            else if (*s == '+' || *s == '-')
            {
                char TopElement = Top(Optr);  //取运算符栈顶操作符,与读取的操作符比较优先级
                switch (TopElement)
                {
                case '+':
                case '-':
                case '(':
                case '#':
                    Push(Optr, *s);
                    break;   //栈顶元素优先级低,直接将所读操作符入栈,读取下一个
                case '*':
                case '/':  //栈顶元素优先级高,则进行“计算并且压入”操作
                    do {
                        Calculate(Oper, Optr);  //先做一次计算
                        TopElement = Top(Optr);  //取新的栈顶运算符
                    } while (TopElement == '*' || TopElement == '/'); //栈顶元素优先级高则继续计算,直到栈顶元素优先级低,
                    //到栈顶元素优先级低,压入读取元素
                    Push(Optr, *s);
                    break;
                }
            }
            else
            {
                printf("error!");
                exit(0);
            }
        }
        s++;
    }
    result = Top(Oper);  //操作数栈顶元素即所求结果
    free(Oper);
    free(Optr);  //操作数栈和运算符栈释放掉
    return result;
}

//计算函数: 操作数栈中出2个数和运算符栈中出1个操作符做计算,结果压入操作数栈中
bool Calculate(SqStack* Oper, SqStack* Optr)
{
    ElemType a, b, result;
    char k = Pop(Optr);  //运算符栈中出一个运算符
    a = Pop(Oper);
    b = Pop(Oper);  //操作数栈中出两个数
    switch (k)
    {
    case '+':
        result = b + a; break;
    case '-':
        result = b - a; break;
    case '*':
        result = b * a; break;
    case '/':
        if (a == 0)
        {
            printf("除数不能为 0 !!");   //输出错误信息后终止程序
            exit(0);    //该函数在 stdlib.h 的头文件中,与malloc等函数一样
        }
        else
            result = b / a;
        break;
    }
    Push(Oper, result);   //结果压入Oper操作数栈中
    return true;
}

int main(void)
{
    bool Push(SqStack * p, ElemType n);
    ElemType Pop(SqStack * p);            //出栈,函数类型是栈元素数据类型
    ElemType Top(SqStack * p);        //获取栈顶元素,注意函数返回类型也是栈元素数据类型
    ElemType Expression(char* s);   //求s指向字符串算术表达式的值
    char str[MAXSIZE];
    ElemType result;
    cout << "请输入表达式:(注意:不要输入空格,且输入完成后用#结束)" << endl;
    cin >> str;
    result = Expression(str);
    cout <<"最终结果为:" << result << endl;
    return(0);
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值