计算机软件技术实习 项目一 支持算术表达式求解的计算器(项目实现)

1.计算器页面设计

(1)按钮和显示框的建立

创建完新项目之后,点开Forms进入ui界面,拖拽左侧框中的pushbutton按钮(用于按键制作)和textEdit按钮(用于显示器制作),根据自己的需要来决定按键和显示器的数量,然后进行合适的排版,双击pushbutton按钮更改名称,可以将pushbutton改为任意符号,方便之后计算器运行。

(2)按钮和显示框的属性设置

界面设计结束后,接下来是对pushbutton和textEdit属性的设置。点开ui界面,任意点击一个按钮,会在右边看到这样的界面。
在这里插入图片描述
首先,objectName就是指按钮的名称,考虑到后期需要设置相应的槽函数和信号连接,所以其必须有一个容易区分的名字(根据自己命名习惯修改即可)。此外pushbutton等按钮和显示器都是有默认大小和文本字体大小等默认格式,如果要调整,便可以在下面各种属性中进行修改。
(我所做的界面如下)
在这里插入图片描述

2.按钮槽函数的定义

页面设计完之后,我们需要编写槽函数,来和按钮匹配,QT给出了函数框架,我们只需编写相应功能实现部分。
具体的步骤就是,依次右击已经创建好的按钮,在弹出来的选项中选择“转到槽”,之后便进入到编辑页面,在函数主体中输入下列代码,运行后点击按钮便可显示出来。

   void MainWindow::on_btn0_clicked()
{
    QString s = ui->output->text();
    ui->output->setText(s.append("0"));
}

在这里插入图片描述

3.关键算法的实现

(1)运算符优先级次序函数

int MainWindow::precedence(const QChar &oper)
{
    if(oper.cell()=='('){
        return 0;
    }
    else if(oper.cell()=='+'||oper.cell()=='-'){
        return 1;
    }
    else if(oper.cell()=='*'||oper.cell()=='/'){
        return 2;
    }
    return 0;
}

(2)中缀表达式转后缀表达式函数

void MainWindow::ToPostfix()
{
    QString exp = ui->output->text();
    for(int i=0;i<exp.size();i++)
    {
        if(exp[i].isNumber()||exp[i]=='.')
        {
            postfix_expression.push_back(exp[i]);
        }
        else if(exp[i]=='(')
        {
            signStack.push(exp[i]);
        }
        else if(exp[i]==')')
        {
            postfix_expression.push_back(' ');  //空格用于分隔数字,使其不被认为是一整个数字
            while(signStack.top()!='(')
            {
                postfix_expression.push_back(signStack.pop());
            }
            signStack.pop();
        }
        else if(!signStack.empty())
        {
            postfix_expression.push_back(' ');
            if (precedence(exp[i])>precedence(signStack.top()))
            {
                signStack.push(exp[i]);
            }
            else
            {
                //qDebug()<<postfix_expression;   //输出表达式
                postfix_expression.push_back(signStack.pop());
                signStack.push(exp[i]);
            }
        }
        else {
            postfix_expression.push_back(' ');
            signStack.push(exp[i]);
        }

    }
    while(!signStack.empty())
    {
        QChar c = signStack.pop();
        postfix_expression.push_back(' ');
        postfix_expression.push_back(c);
    }
}

(3)实现后缀表达式计算函数

void MainWindow::calculate()
{
    QString extra;        //创建一个临时字符数组,用于转换
    QStack<double> ans; //创建栈用于运算和储存结果
    for(int i=0;i<postfix_expression.size();i++)
    {
        if(postfix_expression[i].isNumber()||postfix_expression[i]=='.')
        {
            extra.push_back(postfix_expression[i]);
        }
        else if(postfix_expression[i]==' ')
        {
             if(!extra.isEmpty())
             {
                ans.push(extra.toDouble());    //toDouble()函数 将字符型转化为浮点型数据  并入栈
                extra.clear();                 //转化完了后清空
             }
        }
        else
        {
            double a,b;
            a=ans.pop();
            b=ans.pop();

            if(postfix_expression[i].cell()=='+'){
                ans.push(b+a);
            }
            else if (postfix_expression[i].cell()=='-'){
                ans.push(b-a);
            }
            else if (postfix_expression[i].cell()=='*'){
                ans.push(b*a);
            }
            else if (postfix_expression[i].cell()=='/'){
                if(a!=0)   ans.push(b/a);
                else
                {
                      ui->outans->setText("除数不能为零!");
                      return;
                }
            }
        }

    }
    //计算器屏幕显示结果
    ui->outans->setText(QString::number(ans.top()));
}

4.运算逻辑处理

对于连续输入的运算符,后一个将覆盖前一个;
针对某种特殊情况,需要补“0”

void MainWindow::symbClicked()
{
    QString symbol = ((QPushButton*)sender())->text();
    QString exp = ui->output->text();

    if(exp.right(1) == "+" || exp.right(1) == "-" || exp.right(1) == "*" || exp.right(1) == "/")
        exp = exp.left(exp.size() - 1);
    else if (exp == "" || exp.right(1) == "("||exp.right(1) == ".")
        exp = exp + "0";

    ui->output->setText(exp.append(symbol));
    pointJudge = false;
}

槽函数“等于”的编辑

void MainWindow::on_btn_equal_clicked()
{
    if (count!=0) ui->outans->setText("左右括号不匹配!");
    else
    {
    ToPostfix();
    calculate();
    QString s = ui->output->text();
    QString r= ui->outans->text();
    history.push_back(s);
    ui->out_history->append(s);

    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值