嵌入式Qt 计算器核心算法_2

news2024/11/16 22:30:09

一.中缀表达式转后缀表达式

中缀表达式是最常用的算术表达式形式——运算符在运算数中间。但运算时需要考虑运算符优先级

​后缀表达式是计算机容易运算的表达式,运算符在运算数后面,从左到右进行运算,无需考虑优先级,运算呈线性结构

1 + 2 * 3// 中缀表达式
1 2 3 * +// 后缀表达式

二.转换思路

 

三.代码实现

#include "QCalculatorDec.h"

#include <QDebug>

QCalculatorDec::QCalculatorDec()
{
    m_exp = "";
    m_result = "";

    QQueue<QString> r = split(" 1 + 2 * 3 ");

    for(int i=0; i<r.length(); i++)
    {
        qDebug() << r[i];
    }

    QQueue<QString> output;

    transform(r, output);

    for(int i=0; i<output.length(); i++)
    {
        qDebug() << output[i];
    }
}

QCalculatorDec::~QCalculatorDec()
{

}

bool QCalculatorDec::isDigitOrDot(QChar c)
{
    return (('0' <= c) && (c <= '9')) || (c == '.');
}

bool QCalculatorDec::isSymbol(QChar c)
{
    return isOperator(c) || (c == '(') || (c == ')');
}

bool QCalculatorDec::isSign(QChar c)
{
    return (c == '+') || (c == '-');
}

bool QCalculatorDec::isNumber(QString s)
{
    bool ret = false;

    s.toDouble(&ret);

    return ret;
}

bool QCalculatorDec::isOperator(QString s)
{
    return (s == "+") || (s == "-") || (s == "*") || (s == "/");
}

bool QCalculatorDec::isLeft(QString s)
{
    return (s == "(");
}

bool QCalculatorDec::isRight(QString s)
{
    return (s == ")");
}

int QCalculatorDec::priority(QString s)
{
    int ret = 0;

    if( (s == "+") || (s == "-") )
    {
        ret = 1;
    }

    if( (s == "*") || (s == "/") )
    {
        ret = 2;
    }

    return ret;
}

bool QCalculatorDec::expression(const QString& exp)
{
    bool ret = false;

    return ret;
}

QString QCalculatorDec::result()
{
    return m_result;
}

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 == "") || (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;
    int len = exp.length();
    QStack<QString> stack;

    for(int i=0; i<len; i++)
    {
        if( isLeft(exp[i]) )
        {
            stack.push(exp[i]);
        }
        else if( isRight(exp[i]) )
        {
            if( !stack.isEmpty() && isLeft(stack.top()) )
            {
                stack.pop();
            }
            else
            {
                ret = false;
                break;
            }
        }
    }

    return ret && stack.isEmpty();
}

bool QCalculatorDec::transform(QQueue<QString>& exp, QQueue<QString>& output)
{
    bool ret = match(exp);
    QStack<QString> stack;

    output.clear();

    while( ret && !exp.isEmpty() )
    {
        QString e = exp.dequeue();

        if( isNumber(e) )
        {
            output.enqueue(e);
        }
        else if( isOperator(e) )
        {
            while( !stack.isEmpty() && (priority(e) <= priority(stack.top())) )
            {
                output.enqueue(stack.pop());
            }

            stack.push(e);
        }
        else if( isLeft(e) )
        {
            stack.push(e);
        }
        else if( isRight(e) )
        {
            while( !stack.isEmpty() && !isLeft(stack.top()) )
            {
                output.enqueue(stack.pop());
            }

            if( !stack.isEmpty() )
            {
                stack.pop();
            }
        }
        else
        {
            ret = false;
        }
    }

    while( !stack.isEmpty() )
    {
        output.enqueue(stack.pop());
    }

    if( !ret )
    {
        output.clear();
    }

    return ret;
}

 输出:

"1"
"+"
"2"
"*"
"3"
"1"
"2"
"3"
"*"
"+"

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1462889.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

django自定义后端过滤

​ DRF自带的过滤 第一个 DjangoFilterBackend 是需要安装三方库见[搜索&#xff1a;多字段筛选]两外两个是安装注册了rest_framework就有。 如上图&#xff0c;只要配置了三个箭头所指的方向&#xff0c;就能使用。 第一个单字段过滤 用户视图集中加上filterset_fields …

HarmonyOS—添加/删除Module

Module是应用/服务的基本功能单元&#xff0c;包含了源代码、资源文件、第三方库及应用/服务配置文件&#xff0c;每一个Module都可以独立进行编译和运行。一个HarmonyOS应用/服务通常会包含一个或多个Module&#xff0c;因此&#xff0c;可以在工程中创建多个Module&#xff0…

C++模板从入门到入土

1. 泛型编程 如果我们需要实现一个不同类型的交换函数&#xff0c;如果是学的C语言&#xff0c;你要交换哪些类型&#xff0c;不同的类型就需要重新写一个来实现&#xff0c;所以这是很麻烦的&#xff0c;虽然可以cv一下&#xff0c;有了模板就可以减轻负担。 下面写一个适…

Windows下搭建EFK实例

资源下载 elasticSearch &#xff1a;下载最新版本的就行 kibana filebeat&#xff1a;注意选择压缩包下载 更新elasticsearch.yml&#xff0c;默认端口9200&#xff1a; # Elasticsearch Configuration # # NOTE: Elasticsearch comes with reasonable defaults for most …

CSB ---> (XXE)XML基础

本来今天想更一下CSbeacon上线多层的内网机器的&#xff0c;但是刚好今天是年后的第一节课&#xff0c;讲的是XXE的基础&#xff0c;那就来先盘一下基础&#xff01;&#xff01; 1.XXE XXE全称是XML External Entity即xml外部实体注入攻击&#xff01;其后果会导致用户…

UE C++ 设置碰撞前 后事件 碰撞中事件

一.在Actor中声明碰撞BOX组件 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category "MySceneComponent")class UBoxComponent* MyBox; 在Actor以这样的形式实现代理绑定&#xff0c;在BeginPlay()里。 MyBox->OnComponentBeginOverlap.AddDynamic(); 转到…

《游戏引擎架构》--学习3

内存管理 优化动态内存分配 维持最低限度的堆分配&#xff0c;并且永不在紧凑循环中使用堆分配 容器 迭代器 Unicode

(C++) 详解内存地址空间

详解内存空间 0. 概述 一个C/C 程序&#xff0c;编译之后&#xff0c;形成的程序&#xff0c;在执行期间&#xff0c;内存中不仅存在一块区域用于存放代码&#xff0c;还有一些其他的区域用于使用&#xff0c;本节会详解C/C内部所使用的内存地址空间&#xff0c;关于各内存的…

Java下访问SQLServer 2008(低于2016)数据连接问题

环境&#xff1a;ubuntu20.04&#xff0c;tomcat&#xff0c;java 通过jdbc:sqlserver连接远程的SQLServer 2008R2数据库&#xff0c;2016版本之前仅支持TLS10&#xff0c;因此在连接时会出现如下错误&#xff0c; The driver could not establish a secure connection to SQ…

(二十二)Flask之上下文管理第三篇【收尾—讲一讲g】

目录&#xff1a; 每篇前言&#xff1a;g到底是什么&#xff1f;生命周期在请求周期内保持数据需要注意的是&#xff1a; 拓展—面向对象的私有字段深入讲解一下那句&#xff1a; 每篇前言&#xff1a; &#x1f3c6;&#x1f3c6;作者介绍&#xff1a;【孤寒者】—CSDN全栈领域…

Java项目:21 基于SSM实现的图书借阅管理系统

作者主页&#xff1a;舒克日记 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文中获取源码 项目介绍 基于SSM实现的图书借阅管理系统设计了两个角色&#xff0c;分别是管理员、用户&#xff0c;在数据表user中以ident字段区分&#xff0c;为1表示管理员…

Vue中如何使用dayjs

Day.js中文网Day.js是一个极简的JavaScript库&#xff0c;可以为现代浏览器解析、验证、操作和显示日期和时间。https://dayjs.fenxianglu.cn/ 单位不区别大小写&#xff0c;支持复数和缩写形式 单位缩写描述 date D日期 [1,31]dayd星期 [0,6]&#xff08;星期日0&#xff0c…

【开源】JAVA+Vue.js实现超市账单管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3.3 后端设计在这里插入图片描述 四、系统展示五、核心代码5.1 查询供应商5.2 查询商品5.3 新增超市账单5.4 编辑超市账单5.5 查询超市账单 六、免责说明 一、摘要 1.1 项目介绍 基于…

尾矿库排洪系统结构仿真软件WKStruc(可试用)

1、背景介绍 尾矿库作为重大危险源之一&#xff0c;在国际灾害事故排名中位列第18位&#xff0c;根据中国钼业2019年8月刊《中国尾矿库溃坝与泄漏事故统计及成因分析》的统计&#xff0c;在46起尾矿库泄漏事故中&#xff0c;由于排洪设施导致的尾矿泄漏事故占比高达1/3&#x…

【SpringCloud】使用 Spring Cloud Alibaba 之 Sentinel 实现微服务的限流、降级、熔断

目录 一、Sentinel 介绍1.1 什么是 Sentinel1.2 Sentinel 特性1.3 限流、降级与熔断的区别 二、实战演示2.1 下载启动 Sentinel 控制台2.2 后端微服务接入 Sentinel 控制台2.2.1 引入 Sentinel 依赖2.2.2 添加 Sentinel 连接配置 2.3 使用 Sentinel 进行流控&#xff08;含限流…

【LeetCode: 105. 从前序与中序遍历序列构造二叉树 + DFS】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

【精选】Java面向对象进阶——内部类

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收藏 …

设计师常常从哪些网站获取灵感?

1、Pinterest Pinterest是一个基于图片共享的社交网站。用户可以在平台上浏览、收集和分享各种想法、设计灵感和项目。Pinterest用户可以在其网站或应用程序上创建虚拟画板&#xff08;boards&#xff09;&#xff0c;根据主题或兴趣收集和整理你最喜欢的图片&#xff08;包括…

RxJS 核心原理-操作符(源码实现)

本文将深入探讨RXJS操作符的核心原理&#xff0c;并介绍一些常见的操作符、应用场景以及相应的代码示例。通过理解RXJS的响应式编程思想&#xff0c;您将能够更好地应用它来处理异步数据流和事件流。 建议读者在阅读本文之前&#xff0c;先参考我的另一篇文章《深入浅出 RxJS …

IDM(Internet Download Manager)2024免激活绿色版下载

IDM&#xff08;Internet Download Manager&#xff09;在安全保护方面提供了多种功能和策略&#xff0c;以确保用户的下载体验和数据安全。以下是一些IDM的安全保护功能和策略&#xff1a; IDM绿色下载如下: https://wm.makeding.com/iclk/?zoneid34275 病毒扫描功能&#…