实验一、计算器

1、 项目概述
1.1 项目目标和主要内容
本项目实现的主要内容和目标为实现算术表达式的求解
采用的开发工具为:qt creator 5.14.2
1.2 项目的主要功能
实现运算符(即操作符)为+、-、*、/(加、减、乘、除)等二元操作符,包括圆括号;以及输入的式子显示出来以及能够查看历史记录,
2、 项目设计
2.1 项目总体框架
用qt内置的按钮设置函数来定义按钮,以及用函数定义按钮的功能,并将按钮与函数连接起来
2.2 系统详细设计
用qt的界面设置函数来定义计算器的布局,以及对输入错误计算式子进行判断,将表达式转换为后缀表达式。
2.3 关键算法分析
算法 1:定义按钮
QLineEdit *inputLine;//显示框
QString input=“0”; //输入框
bool flat=false;
//0-9按钮
QPushButton *zeroButton;
QPushButton *oneButton;
QPushButton *twoButton;
QPushButton *threeButton;
QPushButton *fourButton;
QPushButton *fiveButton;
QPushButton *sixButton;
QPushButton *sevenButton;
QPushButton *eightButton;
QPushButton *nineButton;

  QPushButton *addButton;
  QPushButton *subButton;
  QPushButton *divButton;
  QPushButton *mulButton;
  QPushButton *equButton;
  QPushButton *hisButton; //Time
  QPushButton *decButton;
  QPushButton *botButton;

  QPushButton *CEButton;
  QPushButton *ACButton;
  QPushButton *lefButton;
  QPushButton *rigButton;

private slots:

  void buttonZeroClicked();
  void buttonOneClicked();
  void buttonTwoClicked();
  void buttonThreeClicked();
  void buttonFourClicked();
  void buttonFiveClicked();
  void buttonSixClicked();
  void buttonSevenClicked();
  void buttonEightClicked();
  void buttonNineClicked();


  void buttonAddClicked();//+
  void buttonSubClicked();//-
  void buttonMulClicked();//乘
  void buttonDivClicked();//除
  void buttonhisClicked(); //时间
  void buttonDecClicked();//小数点
  void buttonBotClicked(); //加减号

  void buttonEquClicked();//等于号

  void buttonLefClicked();//左括号
  void buttonRigClicked();//右括号

  void buttonCEClicked();//CE
  void buttonACClicked();//AC

};

QWidget *widget=new QWidget;
//构建一个QWidget布局将设置的布局添加进这个QWidget
this->setCentralWidget(widget);

   inputLine=new QLineEdit;
   inputLine->setText(input);

   zeroButton=new QPushButton("0");
   oneButton=new QPushButton("1");
   twoButton=new QPushButton("2");
   threeButton=new QPushButton("3");
   fourButton=new QPushButton("4");
   fiveButton=new QPushButton("5");
   sixButton=new QPushButton("6");
   sevenButton=new QPushButton("7");
   eightButton=new QPushButton("8");
   nineButton=new QPushButton("9");
   decButton=new QPushButton(".");

   botButton=new QPushButton("±");
   hisButton=new QPushButton("history");
   addButton=new QPushButton("+");
   subButton=new QPushButton("-");
   mulButton=new QPushButton("*");
   divButton=new QPushButton("/");
   equButton=new QPushButton("=");

   lefButton=new QPushButton("(");
   rigButton=new QPushButton(")");
   CEButton=new QPushButton("CE");
   ACButton=new QPushButton("AC");

算法 2:按钮布局
QGridLayout *H=new QGridLayout(this); //声明了一个网格布局

   inputLine->setFixedHeight(50); //调整第一行大小
   CEButton->setFixedHeight(50);
   ACButton->setFixedHeight(50);

   H->addWidget(inputLine,0,0,1,3);
   H->setRowStretch(0,100);
   H->addWidget(CEButton,0,3);
   H->addWidget(ACButton,0,4);

   H->addWidget(oneButton,1,0);
   H->addWidget(twoButton,1,1);
   H->addWidget(threeButton,1,2);
   H->addWidget(botButton,1,3);
   H->addWidget(hisButton,1,4);

   H->addWidget(fourButton,2,0);
   H->addWidget(fiveButton,2,1);
   H->addWidget(sixButton,2,2);
   H->addWidget(addButton,2,3);
   H->addWidget(subButton,2,4);

   H->addWidget(sevenButton,3,0);
   H->addWidget(eightButton,3,1);
   H->addWidget(nineButton,3,2);
   H->addWidget(mulButton,3,3);
   H->addWidget(divButton,3,4);

   H->addWidget(zeroButton,4,0);
   H->addWidget(decButton,4,1);
   H->addWidget(lefButton,4,2);
   H->addWidget(rigButton,4,3);
   H->addWidget(equButton,4,4);

算法 3:信号与槽函数
connect(zeroButton,SIGNAL(clicked()),this,SLOT(buttonZeroClicked()));//信号与槽函数
connect(oneButton,SIGNAL(clicked()),this,SLOT(buttonOneClicked()));
connect(twoButton,SIGNAL(clicked()),this,SLOT(buttonTwoClicked()));
connect(threeButton,SIGNAL(clicked()),this,SLOT(buttonThreeClicked()));
connect(fourButton,SIGNAL(clicked()),this,SLOT(buttonFourClicked()));
connect(fiveButton,SIGNAL(clicked()),this,SLOT(buttonFiveClicked()));
connect(sixButton,SIGNAL(clicked()),this,SLOT(buttonSixClicked()));
connect(sevenButton,SIGNAL(clicked()),this,SLOT(buttonSevenClicked()));
connect(eightButton,SIGNAL(clicked()),this,SLOT(buttonEightClicked()));
connect(nineButton,SIGNAL(clicked()),this,SLOT(buttonNineClicked()));

   connect(addButton,SIGNAL(clicked()),this,SLOT(buttonAddClicked()));
   connect(subButton,SIGNAL(clicked()),this,SLOT(buttonSubClicked()));
   connect(mulButton,SIGNAL(clicked()),this,SLOT(buttonMulClicked()));
   connect(divButton,SIGNAL(clicked()),this,SLOT(buttonDivClicked()));

   connect(botButton,SIGNAL(clicked(bool)),this,SLOT(buttonBotClicked()));//正负号
   connect(hisButton,SIGNAL(clicked(bool)),this,SLOT(buttonhisClicked()));//his
   connect(decButton,SIGNAL(clicked(bool)),this,SLOT(buttonDecClicked()));//点号

   connect(lefButton,SIGNAL(clicked(bool)),this,SLOT(buttonLefClicked()));//左括号
   connect(rigButton,SIGNAL(clicked(bool)),this,SLOT(buttonRigClicked()));//右括号

   connect(CEButton,SIGNAL(clicked()),this,SLOT(buttonCEClicked()));
   connect(ACButton,SIGNAL(clicked()),this,SLOT(buttonACClicked()));

   connect(equButton,SIGNAL(clicked()),this,SLOT(buttonEquClicked())); //等于号*/

算法 4:槽函数

void calculator::buttonZeroClicked() //以下是实现相应的槽函数
{
if(input==“0”)
input=‘0’;
else input=input+‘0’;
inputLine->setText(input);
}

void calculator::buttonOneClicked()
{
if(input==“0”)
input=‘1’;
else input=input+‘1’;
inputLine->setText(input);
}

void calculator::buttonTwoClicked()
{
if(input==“0”)
input=‘2’;
else input=input+‘2’;
inputLine->setText(input);
}

void calculator::buttonThreeClicked()
{
if(input==“0”)
input=‘3’;
else input=input+‘3’;
inputLine->setText(input);
}

void calculator::buttonFourClicked()
{
if(input==“0”)
input=‘4’;
else input=input+‘4’;
inputLine->setText(input);
}

void calculator::buttonFiveClicked()
{
if(input==“0”)
input=‘5’;
else input=input+‘5’;
inputLine->setText(input);
}

void calculator::buttonSixClicked()
{
if(input==“0”)
input=‘6’;
else input=input+‘6’;
inputLine->setText(input);
}

void calculator::buttonSevenClicked()
{
if(input==“0”)
input=‘7’;
else input=input+‘7’;
inputLine->setText(input);
}

void calculator::buttonEightClicked()
{
if(input==“0”)
input=‘8’;
else input=input+‘8’;
inputLine->setText(input);
}

void calculator::buttonNineClicked()
{
if(input==“0”)
input=‘9’;
else input=input+‘9’;
inputLine->setText(input);
}

void calculator::buttonAddClicked()
{
if(input==“0”)
input=’+’;
else input=input+’+’;
inputLine->setText(input);
}

void calculator::buttonSubClicked()
{
if(input==“0”)
input=’-’;
else input=input+’-’;
inputLine->setText(input);
}

void calculator::buttonMulClicked()
{
if(input==“0”)
input=’’;
else input=input+’
’;
inputLine->setText(input);
}

void calculator::buttonDivClicked()
{
if(input==“0”)
input=’/’;
else input=input+’/’;
inputLine->setText(input);
}

void calculator::buttonhisClicked() //history
{

}

void calculator::buttonDecClicked() //小数点
{
if(input==“0”)
input=’.’;
else input=input+’.’;
inputLine->setText(input);
}

void calculator::buttonBotClicked() //加减号
{
if(input==“0”)
input=’-’;
else
{
QString::iterator p=input.end();
p–;
if(’-’==*p)
input=input.left(input.length()-1);
else input=input+’-’;
}
inputLine->setText(input);
}

void calculator::buttonLefClicked()//左括号
{
if(input==“0”)
input=’(’;
else input=input+’(’;
inputLine->setText(input);
}

void calculator::buttonRigClicked()//右括号
{
if(input==“0”)
input=’)’;
else input=input+’)’;
inputLine->setText(input);
}

void calculator::buttonCEClicked()
{
input = input.left(input.length()-1); //减去一字符
inputLine->setText(input);
}
void calculator::buttonACClicked() //直接清空
{
input=‘0’;
inputLine->setText(input);
}

void calculator::buttonEquClicked()//等于号
{
string inputTemp = input.toStdString();
vector expression = midToPost(inputTemp);
double value = getValue(expression);
if(value != INT_MAX) {
input=input+"="+QString::number(value);
inputLine->setText(input);
}else{
input=input+"=syntax error";
inputLine->setText(input);
}
}
算法 5:中缀表达式转换为后缀表达式(双栈储存)
bool isNum(char ch) {
if(ch >= ‘0’ && ch <= ‘9’) return true;
else return false;
}

bool isOperate(char ch) {
if(ch == ‘+’ || ch == ‘-’ || ch == ‘*’ || ch == ‘/’ || ch == ‘(’ || ch == ‘)’)
return true;
else return false;
}

int level(char ch) {
switch(ch) {
case ‘(’ :
return 5;
case ‘*’ :
return 4;
case ‘/’ :
return 4;
case ‘+’ :
return 3;
case ‘-’ :
return 3;
case ‘)’:
return 2;
}
}
/字符串转数字/
double scd(string s) {
if(s.length() == 0) return INT_MAX;

bool flag = false;
for(int i = 0; i < s.length(); i++) {
    if(i == 0 && s[i] == '-') continue;
    else if(s[i] == '.' && !flag) {
        if(i > 0 && isNum(s[i-1])) {
            flag = true;
            continue;
        }
        else return INT_MAX;
    }
    else if(isNum(s[i])) continue;
    else return INT_MAX;
}

double result = atof(s.c_str());
return result;

}

算法 6:表达式判断
vector midToPost(string s) {
stack S; /符号栈/
vector V; /后缀表达式/
int i = 0;
while(i < s.length()) {
if(isNum(s[i])) {
string str = “”;
while(isNum(s[i]) || s[i] == ‘.’) {
str += s[i];
i++;
}
V.push_back(str);
}

    else if(isOperate(s[i])){
        /*负数情况*/
        if(s[i] == '-' && (i == 0 || !isNum(s[i-1]))) {
            string str = "-"; i++;
            while(isNum(s[i]) || s[i] == '.') {
                str += s[i]; i++;
            }
            V.push_back(str);
        }else{
            if(S.empty()){
                S.push(s[i]); i++;
            }else {
                int initial = level(s[i]);
                if(initial == 2) {
                    while(level(S.top()) != 5 && !s.empty()) {
                        string str = "";
                        str += S.top();
                        V.push_back(str);
                        S.pop();
                    }
                    if(S.top() == '(') S.pop(); i++;
                } else {
                    while(!S.empty() && initial <= level(S.top()) && level(S.top()) != 5) {
                        string str = "";
                        str += S.top();
                        V.push_back(str);
                        S.pop();
                    }
                    S.push(s[i]); i++;
                }
            }
        }
    }
    else{
        cout << "表达式出错" << endl;
        V.clear();
        return V;
    }
}

算法 7:后缀表达式得到最终结果
double getValue(vector V) {
stack S;
for(int i = 0; i < V.size(); i++) {
/操作运算符/
if(V[i].length() == 1 && isOperate(V[i][0])) {
double a = 0, b = 0;
if(!S.empty()) {
a = S.top(); S.pop();
}else return INT_MAX;

        if(!S.empty()) {
            b = S.top(); S.pop();
        }else return INT_MAX;

        switch(V[i][0]) {
            case '+':
                S.push(b+a);
                break;
            case '-':
                S.push(b-a);
                break;
            case '*':
                S.push(b*a);
                break;
            case '/':
                S.push(b/a);
                break;
            default:
                return INT_MAX;
        }
    }else {
        if(scd(V[i]) == INT_MAX) return INT_MAX;
        else S.push(scd(V[i]));
    }
}
if(S.empty()) return INT_MAX;

double value = S.top();
S.pop();
return value;

}
3、 程序运行结果分析

4、总结
4.1 项目的难点和关键点
对表达式是否错误进行判断,中缀表达式转换为后缀表达式,以及双栈储存。
4.2 项目的评价
第一次使用qt,对qt了解花了太长时间还没有掌握,想要一直查资料,设计不来界面导致实验重做了好多次。
4.3 心得体会
对qt进行了一定的了解,对程序有了一定的基础,让我了解了一小部分的qt知识,以后对qt了解还有很长的路还要走
5、 参考文献
https://www.bilibili.com/video/BV11U4y1L7b3
https://blog.csdn.net/zycxnanwang/article/details/51505100

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值