Qt 第9课、计算器中缀转后缀算法
计算器核心算法:
1、将中缀表达式进行数字和运算符的分离
2、将中缀表达式转换成后缀表达式
3、通过后缀表达式计算最后的结果

二、计算器中缀转后缀算法
计算器中缀转后缀算法的意义在于把中缀表达式转换成后缀表达式,能够更好地计算
- 算法的基本思路
1、如果是isNumber,直接进输出队列
2、如果是isOperator,
如果一个运算符优先级 <= 前一个运算符优先级,则这个前面那个运算符进输出队列
其余的全部进栈
3、如果是左括号,进栈
4、如果是右括号,直到栈顶为左括号才不用把栈里的进输出队列,
把栈顶元素pop()
5、其余的报错
如果栈里面不为空,直接全部进队列
bool QCalculatorDec::transform(QQueue<QString>& exp, QQueue<QString>& output)
{bool ret = match(exp);output.clear();QStack<QString> stack;while(ret && !exp.isEmpty()){QString str = exp.dequeue();if(isNumber(str)){output.enqueue(str);}else if(isOperator(str)){while(!stack.isEmpty() && priority(str) <= priority(stack.top())){output.enqueue(stack.pop());}stack.push(str);}else if(isLeft(str)){stack.push(str);}else if(isRight(str)){while(!stack.isEmpty() && !isLeft(stack.top())){output.enqueue(stack.pop());}stack.pop();}else{ret = false;}}while(!stack.isEmpty()){output.enqueue(stack.pop());}if(!ret){output.clear();}return ret;
}
4、计算器后缀表达式计算算法
QString QCalculatorDec::calculate(QString l, QString op, QString r)
{QString ret = "Error";if(isNumber(l) && isNumber(r)){double lp = l.toDouble();double rp = r.toDouble();if(op == "+"){ret.sprintf("%f", lp + rp);}else if(op == "-"){ret.sprintf("%f", lp - rp);}else if(op == "*"){ret.sprintf("%f", lp * rp);}else if(op == "/"){double delta = 0.0000000001;if(rp >= -delta && rp <= delta){ret = "Error";}else{ret.sprintf("%f", lp / rp);}}else{ret = "Error";}}return ret;
}QString QCalculatorDec::calculate(QQueue<QString>& exp)
{QString ret = "Error";QStack<QString> stack;while(!exp.isEmpty()){QString str = exp.dequeue();if(isNumber(str)){stack.push(str);}else if(isOperator(str)){QString rp = !stack.isEmpty() ? stack.pop() : "";QString lp = !stack.isEmpty() ? stack.pop() : "";QString result = calculate(lp, str, rp);if(result != "Error"){stack.push(result);}else{break;}}}if(exp.isEmpty() && stack.size() == 1 && isNumber(stack.top())){ret = stack.pop();}return ret;
}
5、通过一个函数包含所有计算器的核心算法
bool QCalculatorDec::expression(const QString& exp)
{bool ret = false;QQueue<QString> spExp = split(exp);QQueue<QString> postExp;m_exp = exp;if(transform(spExp, postExp)){m_result = calculate(postExp);ret = (m_result != "Error");}else{m_result = "Error";}return ret;
}
QString QCalculatorDec::result()
{return m_result;
}
计算器算法实现的源代码:
QCalculatorDec.h
#ifndef QCALCULATORDEC_H
#define QCALCULATORDEC_H
#include <QQueue>
#include <QString>
#include <QStack>#include "ICalculator.h"
class QCalculatorDec
{
protected:QString m_exp;QString m_result;bool isDigitOrDot(QChar c);bool isSign(QChar c);bool isSymbol(QChar c);bool isOperator(QString s);bool isLeft(QString s);bool isRight(QString s);bool isNumber(QString s);int priority(QString s);QQueue<QString> split(const QString& exp);bool match(QQueue<QString>& exp);bool transform(QQueue<QString>& exp, QQueue<QString>& output);QString calculate(QString l, QString op, QString r);QString calculate(QQueue<QString>& exp);
public:QCalculatorDec();bool expression(const QString& exp);QString expression();QString result();~QCalculatorDec();
};#endif // QCALCULATORDEC_H
QCalculatorDec.cpp
#include "QCalculatorDec.h"
#include <QDebug>
QCalculatorDec::QCalculatorDec()
{m_exp = "";m_result = "";
}bool QCalculatorDec::isDigitOrDot(QChar c)
{return ((c >= '0')&&(c <= '9'))||(c == '.');
}bool QCalculatorDec::isSign(QChar c)
{return (c == '+')||(c == '-');
}bool QCalculatorDec::isSymbol(QChar c)
{return isOperator(c)||(c == '(')||(c == ')');
}bool QCalculatorDec::isOperator(QString s)
{return (s == "+")||(s == "-")||(s == "*")||(s == "/");
}bool QCalculatorDec::isLeft(QString s)
{return (s == "(");
}bool QCalculatorDec::isRight(QString s)
{return (s == ")");
}bool QCalculatorDec::isNumber(QString s)
{bool ret = false;s.toDouble(&ret);return ret;
}int QCalculatorDec::priority(QString s)
{int ret = 0;if(s == "+"||s == "-"){ret = 1;}else if(s == "*"||s == "/"){ret = 2;}return ret;
}QQueue<QString> QCalculatorDec::split(const QString& exp)
{QQueue<QString> ret;QString num;QString pre;for(int i = 0; i < exp.length(); i++){if(isDigitOrDot(exp[i])){num += exp[i];pre = exp[i];}else if(isSymbol(exp[i])){if(!num.isEmpty()){ret.enqueue(num);num.clear();}if(isSign(exp[i])&&(pre == "" || isLeft(pre) || isOperator(pre))){num += exp[i];}else{ret.enqueue(exp[i]);}pre = exp[i];}}if(!num.isEmpty()){ret.enqueue(num);}return ret;
}bool QCalculatorDec::match(QQueue<QString>& exp)
{bool ret = true;QStack<QString> stack;for(int i = 0; i < exp.length(); i++){if(isLeft(exp[i])){stack.push(exp[i]);}else if(isRight(exp[i])){if(isLeft(stack.top())){stack.pop();}else{ret = false;}}}if(!stack.isEmpty()){ret = false;}return ret;
}bool QCalculatorDec::transform(QQueue<QString>& exp, QQueue<QString>& output)
{bool ret = match(exp);output.clear();QStack<QString> stack;while(ret && !exp.isEmpty()){QString str = exp.dequeue();if(isNumber(str)){output.enqueue(str);}else if(isOperator(str)){while(!stack.isEmpty() && priority(str) <= priority(stack.top())){output.enqueue(stack.pop());}stack.push(str);}else if(isLeft(str)){stack.push(str);}else if(isRight(str)){while(!stack.isEmpty() && !isLeft(stack.top())){output.enqueue(stack.pop());}stack.pop();}else{ret = false;}}while(!stack.isEmpty()){output.enqueue(stack.pop());}if(!ret){output.clear();}return ret;
}QString QCalculatorDec::calculate(QString l, QString op, QString r)
{QString ret = "Error";if(isNumber(l) && isNumber(r)){double lp = l.toDouble();double rp = r.toDouble();if(op == "+"){ret.sprintf("%f", lp + rp);}else if(op == "-"){ret.sprintf("%f", lp - rp);}else if(op == "*"){ret.sprintf("%f", lp * rp);}else if(op == "/"){double delta = 0.0000000001;if(rp >= -delta && rp <= delta){ret = "Error";}else{ret.sprintf("%f", lp / rp);}}else{ret = "Error";}}return ret;
}QString QCalculatorDec::calculate(QQueue<QString>& exp)
{QString ret = "Error";QStack<QString> stack;while(!exp.isEmpty()){QString str = exp.dequeue();if(isNumber(str)){stack.push(str);}else if(isOperator(str)){QString rp = !stack.isEmpty() ? stack.pop() : "";QString lp = !stack.isEmpty() ? stack.pop() : "";QString result = calculate(lp, str, rp);if(result != "Error"){stack.push(result);}else{break;}}}if(exp.isEmpty() && stack.size() == 1 && isNumber(stack.top())){ret = stack.pop();}return ret;
}bool QCalculatorDec::expression(const QString& exp)
{bool ret = false;QQueue<QString> spExp = split(exp);QQueue<QString> postExp;m_exp = exp;if(transform(spExp, postExp)){m_result = calculate(postExp);ret = (m_result != "Error");}else{m_result = "Error";}return ret;
}QString QCalculatorDec::expression()
{return m_exp;
}QString QCalculatorDec::result()
{return m_result;
}QCalculatorDec::~QCalculatorDec()
{}
相关文章:
Qt 第9课、计算器中缀转后缀算法
计算器核心算法: 1、将中缀表达式进行数字和运算符的分离 2、将中缀表达式转换成后缀表达式 3、通过后缀表达式计算最后的结果 二、计算器中缀转后缀算法 计算器中缀转后缀算法的意义在于把中缀表达式转换成后缀表达式,能够更好地计算 算法的基本思路…...
docker的使用方法
docker技术 同一个操作系统内跑多套不同版本依赖的业务 docker可以使同一个物理机中进程空间,网络空间,文件系统空间相互隔绝 虚拟机弊端:每个需要安装操作系统,太重量级,资源需要提前分配好 部署程序 开发环境 win…...
Kafka(五)生产者向发送消息的执行流程
(1)生产者要往 Kafka 发送消息时,需要创建 ProducerRecoder,代码如下: ProducerRecord<String,String> record new ProducerRecoder<>("CostomerCountry","Precision Products","France&q…...
华为OD机试模拟题 用 C++ 实现 - 简易压缩算法(2023.Q1)
最近更新的博客 【华为OD机试模拟题】用 C++ 实现 - 最多获得的短信条数(2023.Q1)) 文章目录 最近更新的博客使用说明简易压缩算法题目输入输出示例一输入输出说明示例二输入输出说明示例三输入输出说明...
MATLAB R2022b 安装教程
MATLAB R2022b 安装教程MathWorks 于2022年9月发布了 MATLAB 和 Simulink 产品系列的最新版本 Matlab R2022b版本 ,加入两个新产品: Medical Imaging Toolbox — 可视化、配准、分割和标注二维及三维医学图像Simscape Battery — 设计和仿真电池和储能系…...
PCI子系统
很多网络接口卡都是外围组件互联(Peripheral Compaonent Interconnect)设备,必须与Linux PCI子系统协同工作,并非所有的网络接口都是PCI设备,很多嵌入式设备的网络接口连接的就不是PCI总线,这些设备的初始化…...
Spring源码之IoC容器的Bean创建和依赖注入,DefaultListableBeanFactory容器为例
接上篇Spring源码之IoC容器初始化过程,以FileSystemXmlApplicationContext容器为例 因为FileSystemXmlApplicationContext使用的容器为DefaultListableBeanFactory,所以该篇基于DefaultListableBeanFactory的实现分析依赖注入过程。 目录获取Bean的总体流…...
解决小程序页面scroll-view块自身滑动问题
修改scroll-view的style样式 本来通过函数限制高度 style"margin-top:200rpx;"height: calc(100vh - 200rpx - env(safe-area-inset-bottom));会出现整个scroll-view块位置不固定滑动里面的内容后,自己本身在整个页面内上移,将样式改为&#…...
PowerCommand康明斯发电机控制屏维修HMI211
康明斯柴油发电机的监控系统分为普通机组控制屏和智能化机组控制界面。普通操作界面实用于普通的康明斯柴油发电机的控制,康明斯柴油发电机的起动与停止、供电与断电、状态调整等均由手动操作;自动化康明斯柴油发电机控制系统适合于智能化康明斯柴油发电…...
ELK + Kafka 测试
配置file beat输出到 Kafkalogstash服务器从kafka获取数据并输出到es集群在es集群上查看索引kibana界面添加索引查看数据1.配置file beat输出到 Kafka 1.1 Filebeat机器配置数据采集和输出目标 做好域名解析 # vim /usr/local/filebeat/filebeat.yml # 修改输出目标为kafka…...
迁移系统:换电脑或者硬盘转移磁盘文件的方法!
为什么要将操作系统迁移到新驱动? “将操作系统转移到新驱动您好,我刚刚为我的台式机订购了一个新的2TB希捷Barracuda硬盘,我想知道如何将我的Windows 10操作系统与我下载的其他一些软件一起转移过来。我使用新的/大的硬盘,然…...
职场性别报告,男女薪酬仍有差距,男性平均薪酬比女性高29.7%
性别是否影响职业?女性求职比男性更加困难?男性薪酬比女性更有优势?人们一说到警察、建筑师通常会想到高大魁梧的男性形象,一说到幼师、护士往往想到的都是温柔的女性形象,职业好似与性别挂钩;女性求职通常…...
5-Azidopentanoic acid,79583-98-5,5-Azidopentanoic COOH具有高效稳定,高特异性
5-Azidopentanoic acid,5-Azidopentanoic COOH,5-叠氮基戊酸产品规格:1.CAS号:79583-98-52.分子式:C5H9N3O23.分子量:143.074.包装规格:1g,5g,10g,包装灵活&a…...
滴滴前端高频react面试题汇总
说说 React组件开发中关于作用域的常见问题。 在 EMAScript5语法规范中,关于作用域的常见问题如下。 (1)在map等方法的回调函数中,要绑定作用域this(通过bind方法)。 (2)父组件传递…...
能在软路由docker给部署搭建teamsperk服务器么?并且设置好ddns
参考链接(4条消息) 【个人学习总结】使用docker搭建Teamspeak服务器_blcurtain的博客-CSDN博客_teamspeak3 docker(⊙﹏⊙)哎呀,崩溃啦! (tdeh.top)TeamSpeak服务器搭建与使用 - 缘梦の镇 (cmsboy.cn)Openwrt X86 docker运行甜糖-软路由,x86系统,openwrt…...
应用统计学实验1-蒙特卡罗方法求解定积分
目录 1. 用蒙特卡罗方法计算定积分(随机投点法) 2. 用蒙特卡罗方法计算定积分(平均值法)...
用Pyhon编写一个属于自己的nmap
用Pyhon编写一个属于自己的nmap 文章目录用Pyhon编写一个属于自己的nmap导入 socket 模块,确定目标主机 IP 或域名以及需要扫描的端口列表开始扫描、扫描每个端口创建一个 socket 对象,用于建立 TCP 连接尝试连接目标主机的指定端口如果连接成功…...
电信网上用户资管理系统的设计与实现
技术:Java、JSP等摘要:在对目前市面上已经拥有的营业厅功能分析和整理后,为了保证营业厅中多种功能的分层次处理设计了一个的电信网上用户自管理系统,以web页面方式实现了与用户的交互,同时保证了移动电话计费管理系统…...
js函数柯里化-面试手写版
概念 用我自己的话来总结一下,函数柯里化的意思就是你可以一次传很多参数给curry函数,也可以分多次传递,curry函数每次都会返回一个函数去处理剩下的参数,一直到返回最后的结果。 实例 这里还是举几个例子来说明一下࿱…...
【学习笔记】深入理解JVM之类加载机制
【学习笔记】深入理解JVM之类加载机制 以后基本上都在语雀上面更新,大家有兴趣可以看看嗷! 首发地址: 知识库 文章流程图: 1、概述 首先我们先来看看一个 Class 文件所需要经过的一个流程图: 而我们今天要重点需讲的…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
日常一水C
多态 言简意赅:就是一个对象面对同一事件时做出的不同反应 而之前的继承中说过,当子类和父类的函数名相同时,会隐藏父类的同名函数转而调用子类的同名函数,如果要调用父类的同名函数,那么就需要对父类进行引用&#…...
什么是VR全景技术
VR全景技术,全称为虚拟现实全景技术,是通过计算机图像模拟生成三维空间中的虚拟世界,使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验,结合图文、3D、音视频等多媒体元素…...
深入浅出Diffusion模型:从原理到实践的全方位教程
I. 引言:生成式AI的黎明 – Diffusion模型是什么? 近年来,生成式人工智能(Generative AI)领域取得了爆炸性的进展,模型能够根据简单的文本提示创作出逼真的图像、连贯的文本,乃至更多令人惊叹的…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
