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 文件所需要经过的一个流程图: 而我们今天要重点需讲的…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
基于服务器使用 apt 安装、配置 Nginx
🧾 一、查看可安装的 Nginx 版本 首先,你可以运行以下命令查看可用版本: apt-cache madison nginx-core输出示例: nginx-core | 1.18.0-6ubuntu14.6 | http://archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages ng…...

大数据零基础学习day1之环境准备和大数据初步理解
学习大数据会使用到多台Linux服务器。 一、环境准备 1、VMware 基于VMware构建Linux虚拟机 是大数据从业者或者IT从业者的必备技能之一也是成本低廉的方案 所以VMware虚拟机方案是必须要学习的。 (1)设置网关 打开VMware虚拟机,点击编辑…...

2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...

MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
工程地质软件市场:发展现状、趋势与策略建议
一、引言 在工程建设领域,准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具,正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...