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

news2024/11/15 18:27:43

一.后缀表达式实现算数运算思路

 

 

二.算法实现

 

#include "QCalculatorDec.h"

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

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;
    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;
}

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;
}

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 == "/" )
        {
            const double P = 0.000000000000001;

            if( (-P < rp) && (rp < P) )
            {
                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 e = exp.dequeue();

        if( isNumber(e) )
        {
            stack.push(e);
        }
        else if( isOperator(e) )
        {
            QString rp = !stack.isEmpty() ? stack.pop() : "";
            QString lp = !stack.isEmpty() ? stack.pop() : "";
            QString result = calculate(lp, e, rp);

            if( result != "Error" )
            {
                stack.push(result);
            }
            else
            {
                break;
            }
        }
        else
        {
            break;
        }
    }

    if( exp.isEmpty() && (stack.size() == 1) && isNumber(stack.top()) )
    {
        ret = stack.pop();
    }

    return ret;
}

 输出:

"3.000000"

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

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

相关文章

【人工智能学习思维脉络导图】

曾梦想执剑走天涯&#xff0c;我是程序猿【AK】 目录 知识图谱1. 基础知识2.人工智能核心概念3.实践与应用4.持续学习与进展5.挑战与自我提升6.人脉网络 知识图谱 人工智能学习思维脉络导图 1. 基础知识 计算机科学基础数学基础&#xff08;线性代数、微积分、概率论和统计学…

CapCut - 剪映国际版11.1.0

​【应用名称】&#xff1a;CapCut - 剪映国际版 【适用平台】&#xff1a;#Android 【软件标签】&#xff1a;#CapCut #剪映国际版 【应用版本】&#xff1a;11.1.0 【应用大小】&#xff1a;231MB 【软件说明】&#xff1a;软件升级更新。目前大家广泛使用的最令人惊叹、最专…

【MySQL初阶】索引与事务

1. 索引 1.1 索引基本概念 1.1.1 索引介绍 索引(index)&#xff1a;是一种特殊的文件&#xff0c;包含着对数据表里所有记录的引用指针。可以对表中的一列或者多列创建索引&#xff0c;并指定索引的类型&#xff0c;各类索引有各自的数据结构实现。&#xff08;具体细节在My…

Kafka3.x进阶

来源&#xff1a;B站 目录 Kafka生产者生产经验——生产者如何提高吞吐量生产经验——数据可靠性生产经验——数据去重数据传递语义幂等性生产者事务 生产经验——数据有序生产经验——数据乱序 Kafka BrokerKafka Broker 工作流程Zookeeper 存储的 Kafka 信息Kafka Broker 总…

SDWAN组网基于软件,部署灵活且周期

在当今数字化时代&#xff0c;企业网络架构面临着日益复杂的挑战。传统的硬件路由器和专线连接已经不能满足企业对网络带宽、灵活性和安全性的需求。SD-WAN组网作为一种新兴的网络架构技术&#xff0c;通过基于软件的虚拟化和智能路由功能&#xff0c;为企业提供了部署灵活且周…

“警示”!中国大连证监局等七部门紧急发文:防范虚拟货币非法集资!受害人主要为中老年群体?

“国家发行了一种数字货币&#xff0c;一个人只能买一单&#xff0c;一单1000元&#xff0c;到年底时保底能赚回来5万元”……如此拙劣的骗局&#xff0c;6年间让超过1万名受害人上当。 2023年下半年&#xff0c;福建省漳州市公安机关成功打掉这一诈骗犯罪团伙&#xff0c;查明…

一样的代码不同项目跳转页面报404的解决办法

今天收到实施反馈的一个问题&#xff0c;点项目名称跳转项目详情页面时&#xff0c;有的页面跳转显示正常&#xff0c;有的页面跳转报404错误。错误如下&#xff1a; 发现报错的项目都有一个共性就是有特殊字符“[ ]” , 解决的办法就是把带有特殊字符的字段 用 encodeURI()…

HarmonyOS Stage模型基本概念讲解

本文 我们来说harmonyos中的一种应用模型 Stage模型 官方提供了两种模型 一种是早期的 FA模型 另一种就是就是 harmonyos 3.1才开始的新增的一种模型 Stage模型 目前来讲 Stage 会成为现在乃至将来 长期推进的一种模型 也就是 无论是 现在的harmonyos 4.0 乃至 之后要发布的 …

LeetCode.106. 从中序与后序遍历序列构造二叉树

题目 106. 从中序与后序遍历序列构造二叉树 分析 前面讲过根据前序和中序构建二叉树&#xff1a;博客链接 这道题是告诉我们一颗二叉树的后序和中序&#xff0c;让我们根据后序和中序构造出整颗二叉树。 拿到这道题&#xff0c;我们首先要知道中序的后序又怎样的性质&#…

时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测

时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测 目录 时序预测 | Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 Matlab实现BO-LSSVM贝叶斯算法优化最小二乘支持向量机时间…

【GStreamer】GstElement详解:GStreamer 中最重要的对象

1、什么是元素GstElement? 每个解码器、编码器、解复用器、视频或音频输出实际上都是一个GstElement。GstElement可以视为一个黑盒子:例如,对于解码器元素,输入为已编码数据,输出为解码后的数据,解码过程已由GstElement封装好。 2、都有哪些元素GstElement? 2.1 源点…

PG索引分析示例

名Index MethodTable Name约束字段唯一键并发idx_alarm_originator_alarm_typeB-Treealarmoriginator_id "pg_catalog"."uuid_ops" ASC NULLS LAST, type COLLATE "pg_catalog"."default" "pg_catalog"."text_ops"…

2024-02-22(Spark)

1.Spark Application程序入口为&#xff1a;SparkContext&#xff0c;任何一个应用首先需要构建SparkContext对象&#xff0c;两个步骤构建&#xff1a; 第一步&#xff0c;创建SparkConf对象。设置Spark Application基本信息&#xff0c;比如应用的名称AppName和应用运行Mast…

【PX4SimulinkGazebo联合仿真】在Simulink中使用ROS2控制无人机沿自定义8字形轨迹正向飞行(带偏航角控制)并在Gazebo中可视化

在Simulink中使用ROS2控制无人机沿自定义8字形轨迹正向飞行&#xff08;带偏航角控制&#xff09;并在Gazebo中可视化 系统架构Matlab官方例程Control a Simulated UAV Using ROS 2 and PX4 Bridge运行所需的环境配置PX4&Simulink&Gazebo联合仿真实现方法建立Simulink模…

渗流量监测方法有哪些,怎么选择?

在水利工程中&#xff0c;渗流量的监测是至关重要的&#xff0c;因为它直接影响着建筑物的安全和性能。渗流量观测就是观测和分析在水头作用下渗过建筑物和地基的水量。为了准确测量这一数据&#xff0c;我们需要选择合适的监测方法。那么&#xff0c;如何选择渗流量监测方法呢…

Nginx跳转模块location

一.location模块概述 1.定义 location块是server块的一个指令。作用&#xff1a;基于Nginx服务器接收到的请求字符串&#xff0c;虚拟主机名称&#xff08;ip&#xff0c;域名&#xff09;、url匹配&#xff0c;对特定请求进行处理。 2.三种匹配类别 精准匹配&#xff1a;l…

LeetCode刷题---对称二叉树

解题思路: 首先对二叉树进行判空&#xff0c;如果根节点为空&#xff0c;则返回true 接下来对当前节点的左节点和右节点进行判断 1.如果左节点和右节点同时为空&#xff0c;则返回true。 2.如果左节点和右节点只有一个为空时&#xff0c;返回false。 3.如果左节点的值和右节点的…

独家深度 | 一文看懂 ClickHouse vs Elasticsearch:谁更胜一筹?

简介&#xff1a; 本文的主旨在于通过彻底剖析ClickHouse和Elasticsearch的内核架构&#xff0c;从原理上讲明白两者的优劣之处&#xff0c;同时会附上一份覆盖多场景的测试报告给读者作为参考。 作者&#xff1a;阿里云数据库OLAP产品部 仁劼 原文地址:https://developer.ali…

时序预测demo 代码快速实现 MLP效果比LSTM 好,简单模拟数据

【PyTorch修炼】用pytorch写一个经常用来测试时序模型的简单常规套路&#xff08;LSTM多步迭代预测&#xff09; 层数的理解&#xff1a; LSTM&#xff08;长短期记忆&#xff09;的层数指的是在神经网络中堆叠的LSTM单元的数量。层数决定了网络能够学习的复杂性和深度。每一层…

PLC_博图系列☞基本指令“插入输入”

PLC_博图系列☞基本指令“插入输入” 文章目录 PLC_博图系列☞基本指令“插入输入”背景介绍插入输入说明参数示例 关键字&#xff1a; PLC、 西门子、 博图、 Siemens 、 插入输入 背景介绍 这是一篇关于PLC编程的文章&#xff0c;特别是关于西门子的博图软件。我并不是专…