栈应用——逆波兰算法

这篇具有很好参考价值的文章主要介绍了栈应用——逆波兰算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

个人主页:【😊个人主页】
系列专栏:【❤️数据结构与算法】
学习名言:传屐朝寻药,分灯夜读书

系列文章目录

第一章 ❤️ 学前知识
第二章 ❤️ 单向链表
第三章 ❤️ 递归
第四章 ❤️ 顺序栈
第五章 ❤️ 队列



前言

在我们进行数字运算时我们会根据优先级自然的将结果算出来如同喝水一样,这是因为我们在学习算数开始就已经对这种运算方式习以为常了,但只能分辨出0和1的计算机又是如何进行运算的呢?🤔🤔🤔

中缀表达式?

例如a+b,运算符在两个操作数的中间。这是我们一直习惯使用的表达式形式

后缀表达式

例如a b + ,运算符在两个操作数的后面。这是一种利于计算机处理的表达形式

逆波兰表达式(中缀表达式转后缀表达式)

逆波兰表达式又叫做后缀表达式。在通常的表达式中,二元运算符总是置于与之相关的两个运算对象之间,这种表示法也称为中缀表示。波兰逻辑学家J.Lukasiewicz于1929年提出了另一种表示表达式的方法,按此方法,每一运算符都置于其运算对象之后,故称为后缀表示。

为啥要使用逆波兰表达式

逆波兰表达式是一种十分有用的表达式,它将复杂表达式转换为可以依靠简单的操作得到计算结果的表达式。例如(a+b)(c+d)转换为ab+cd+
去除原来表达式中的括号,因为括号只指示运算顺序,不是实际参与计算的元素。
使得运算顺序有规律可寻,计算机能编写出代码完成计算。
栈应用——逆波兰算法

实现原理

一、如果输入的是操作数,则直接追加入。当输入的是 运算符 或者 分界符时压入栈中
1. 如果是左括号 ‘(’, 则 直接压入栈中,等待下一个最近的 右括号 与之配对。
2. 如果是右括号 ‘)’,则说明有一对括号已经配对(在表达式输入无误的情况下)。那我们就不将它压栈,而是直接将它丢弃😶‍🌫️,然后出栈,得到元素d,将d依次运算。一直循环,直到出栈元素d 是 左括号 ( ,我们同样丢弃他。
(3)如果是运算符
1.如果栈顶元素不是运算符,则二者没有可比性,则直接将此运算符压栈。 例如栈顶是左括号 ( ,或者栈为空。
2.如果栈顶元素是运算符 ,则比较进入的运算符和栈顶运算符的优先级。如果进入运算符 > 栈顶运算符 ,则直接将此运算符压栈。
如果不满足,则将栈顶运算符出栈,再试图将运算符压栈,如果如果依然不满足 ,继续将新的栈顶运算符弹出 ,直到该运算符可以压入栈中为止。
也就是说,如果在栈中,有2个相邻的元素都是运算符,则他们必须满足:下层运算符的优先级一定小于上层元素的优先级,才能相邻。
最后,如果栈中还有元素,则依次弹出追加到d后,就得到了后缀表达式。文章来源地址https://www.toymoban.com/news/detail-406786.html

代码实现

#include <ctype.h>
#define STACK_INIT_SIZE 20 //栈的初始化空间大小
#define STACKINCREMENT        10 //每次增加的栈空间大小
#define MAXBUFFER                10 //缓冲区大小
typedef double ElemType;
typedef struct
{
    int stackSize;
    ElemType* base;//指向栈底的指针
    ElemType* top;//指向栈顶的指针

}sqStack;
void initStack(sqStack* s)
{
    s->base = (ElemType*)malloc(STACK_INIT_SIZE * sizeof(ElemType));
    if (!s->base)
    {
        exit(0);
    }
    s->top = s->base;
    s->stackSize = STACK_INIT_SIZE;
}
void Push(sqStack* s, ElemType e)//进栈
{
    if (s->top - s->base >= s->stackSize)
    {
        s->base = (ElemType*)realloc(s->base, (s->stackSize + STACKINCREMENT) * sizeof(ElemType));
        if (!s->base)
        {
            exit(0);
        }

        s->top = s->base + s->stackSize;
        s->stackSize = s->stackSize + STACK_INIT_SIZE;//大小要更新,不然会误认为容量不够又继续申请内存
    }

    *(s->top) = e;//把e对应的元素压入栈顶
    s->top++;//栈顶上移
}
void Pop(sqStack* s, ElemType* e)//出栈
{
    if (s->top == s->base)//判断栈是不是空
    {
        return;
    }
    *e = *--(s->top);
}
int stackLen(sqStack s)//计算栈的当前容量,s.stackSize
{
    return (s.top - s.base);
}
int main()
{
    char c;
    sqStack s;
    int i = 0;
    double d, e;//临时变量
    char str[MAXBUFFER];//小数存放缓冲区
    initStack(&s);
    printf("请输入逆波兰表达式,数据与运算符之间用空格隔开,按#键结束!\n");
    scanf("%c", &c);
    while (c != '#')
    {
        while (isdigit(c) || c == '.')//判断c是数字,头文件ctype.h,过滤数字和点以外的数据
        {
            str[i++] = c;
            str[i] = '\0';//给不知道下一个是否还要字符的位置赋结束符,以免不知道多长
            if (i >= MAXBUFFER)//字符串溢出
            {
                printf("\n出错:输入的单个数据过长!\n");
                return -1;
            }
            scanf("%c", &c);//继续输入数据
            if (c == ' ')//输入空格,代表单个数据输入结束
            {
                d = atof(str);//把字符串str转化为浮点数
                Push(&s, d);
                i = 0;//i初始化,进入下一个循环
                break;
            }

        }
        switch (c)
        {
        case '+'://两个出栈,并相加
            Pop(&s, &e);//出栈第一个数,给e
            Pop(&s, &d);//出栈第二个数,给d
            Push(&s, d + e);
            break;

        case '-'://两个出栈,并相减
            Pop(&s, &e);//出栈第一个数,给e
            Pop(&s, &d);//出栈第二个数,给d
            Push(&s, d - e);
            break;

        case '*'://两个出栈,并相乘
            Pop(&s, &e);//出栈第一个数,给e
            Pop(&s, &d);//出栈第二个数,给d
            Push(&s, d * e);
            break;

        case '/'://两个出栈,并相除
            Pop(&s, &e);//出栈第一个数,给e
            Pop(&s, &d);//出栈第二个数,给d
            if (e != 0)
            {
                Push(&s, d / e);
            }
            else
            {
                printf("\n错误:除数为零!\n");
                return -1;
            }
            break;
        }

        scanf("%c", &c);
    }
    Pop(&s, &d);//最终的结算结果放在d里
    printf("计算结果为:%f\n", d);
    return 0;
}

到了这里,关于栈应用——逆波兰算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 算法训练day11Leetcode20有效的括号1047删除字符串中所有相邻重复项150逆波兰表达式求值

    https://leetcode.cn/problems/valid-parentheses/description/ https://programmercarl.com/0020.%E6%9C%89%E6%95%88%E7%9A%84%E6%8B%AC%E5%8F%B7.html 判断右括号后忘记pop 括号匹配是使用栈解决的经典问题。 如果还记得编译原理的话,编译器在 词法分析的过程中处理括号、花括号等这个符号的逻辑,也是使用了栈

    2024年01月17日
    浏览(76)
  • 栈|逆波兰表达式求值

    逆波兰表达式求值 逆波兰表达式就是后缀表达式,我们平时写的带括号的是中缀表达式。区分中缀表达式和后缀表达式 就是 操作数 和 操作符 的先后关系。 操作符在后 就是后缀表达式 后缀表达式 的用途就是 让计算机直到计算的先后顺序! 比如 我们中缀表达式 a * (b -

    2024年04月11日
    浏览(48)
  • C++题解 | 逆波兰表达式相关

    ✨个人主页: 北 海 🎉所属专栏: C/C++相关题解 🎊每篇一句: 图片来源 A year from now you may wish you had started today. 明年今日,你会希望此时此刻的自己已经开始行动了。 好久没有更新题解系列博客了,今天要学习的是 逆波兰表达式 ,作为计算机中的重要概念,值得花时间去

    2024年02月02日
    浏览(36)
  • PTA: h0116. 波兰表达式

    (PTA题目描述有误,应该是波兰表达式)逆波兰表达式是一种把运算符前置的算术表达式,例如普通的表达式2 + 3的逆波兰表示法为+ 2 3。逆波兰表达式的优点是运算符之间不必有优先级关系,也不必用括号改变运算次序,例如(2 + 3) * 4的逆波兰表示法为* + 2 3 4。本题求解逆波

    2024年02月06日
    浏览(38)
  • 『力扣刷题本』:逆波兰表达式求值

    大家好久不昂,最近 1 个多月罗根一直在备考期末,文章发的很少。 现在已经放寒假啦,学习自然也不能拉下,毕竟 4 月份就要去参加蓝桥杯了。 先给自己定个小目标,日更 2 篇! 咳咳,下面马上开始讲题👇 给你一个字符串数组  tokens  ,表示一个根据 逆波兰表示法 表

    2024年01月16日
    浏览(41)
  • LeetCode:150. 逆波兰表达式求值—栈

    🍎道阻且长,行则将至。🍓 🌻算法,不如说它是一种思考方式🍀 算法专栏: 👉🏻123 题目描述 :给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 来源:力扣(LeetCode) 难度: 简单 提示:

    2023年04月16日
    浏览(66)
  • JAVA练习99-逆波兰表达式求值

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一、题目-逆波兰表达式求值 1.题目描述 2.思路与代码 2.1 思路 2.2 代码 总结 提示:这里可以添加本文要记录的大概内容: 4月5日练习内容 提示:以下是本篇文章正文内容,下面案例可供参考

    2023年04月08日
    浏览(47)
  • 【leetcode C++】逆波兰表达式求值

    给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为 \\\'+\\\'、\\\'-\\\'、\\\'*\\\' 和 \\\'/\\\' 。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个整数之间的除法总是 向零截断

    2024年03月16日
    浏览(77)
  • 【数据结构】你知道波兰表达式和逆波兰表达式吗?我才知道原来栈在表达式求值中还能这样使用……

    大家好,很高兴又和大家见面啦!!! 在前面的内容中我们详细介绍了栈的第一种应用——在括号匹配问题中的应用,如果还没有阅读过的朋友可以回看前面两篇文章。在今天的内容中我们将介绍栈的另一种应用——在表达式求值中的应用。 表达式相信大家应该不陌生了,

    2024年04月27日
    浏览(41)
  • 力扣:150. 逆波兰表达式求值(Python3)

    给你一个字符串数组  tokens  ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算符为  \\\'+\\\' 、 \\\'-\\\' 、 \\\'*\\\'  和  \\\'/\\\'  。 每个操作数(运算对象)都可以是一个整数或者另一个表达式。 两个整数之间的除法总

    2024年02月05日
    浏览(57)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包