计算器第四版:C++,QT

 核心算法和第二版一样:

头文件:calculate.h

#ifndef CALCULATE_H
#define CALCULATE_H
 
#include <QMainWindow>
#include<QPushButton>
#include<QLineEdit>
#include<QHBoxLayout>
#include<QVBoxLayout>
#include<QGridLayout>
#include<QString>
#include<QStack>
#include<QTime>
 
//extern QStack<double>Data;
//extern QStack<char>Symb;
 
class calculate : public QMainWindow
{
    Q_OBJECT
    
public:
    calculate(QWidget *parent = 0);
    ~calculate();
   // static QStack<double>Data;
   // static QStack<char>Symb;
 
private:
          QLineEdit *inputLine;//显示框
          QString input="0"; //输入框
 
          //0-9:十个按钮
          QPushButton *zeroButton;
          QPushButton *oneButton;
          QPushButton *twoButton;
          QPushButton *threeButton;
          QPushButton *fourButton;
          QPushButton *fiveButton;
          QPushButton *sixButton;
          QPushButton *sevenButton;
          QPushButton *eightButton;
          QPushButton *nineButton;
 
          //运算符8个,两个功能键
          QPushButton *addButton;// '+'
          QPushButton *subButton;// '-'
          QPushButton *mulButton;// '*'
          QPushButton *divButton;// '/ '
 
          QPushButton *equButton;// '='
          QPushButton *decButton;// '.'
          QPushButton *lefButton;// '('
          QPushButton *rigButton;// ')'
 
          QPushButton *CEButton; //清除一个字符
          QPushButton *ACButton; //全部清除
 
 
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 buttonEquClicked();//等于号
      void buttonDecClicked();//小数点
 
      void buttonLefClicked();//左括号
      void buttonRigClicked();//右括号
 
      void buttonCEClicked();//CE
      void buttonACClicked();//AC
 
 
};
 
#endif // CALCULATE_H
 

源文件:calculate.cpp

#include "calculate.h"
 
//QStack<double> Data;
//QStack<char> Symb;
 
double allocate(const char *S); //数和运算符分类
QStack<char> check(char c,QStack<double>* Data, QStack<char> Symb);//运算符分类处理
int  getPri(char c); //计算优先级
QStack<char> calcu(QStack<double>* Data, QStack<char> Symb);//计算栈顶元素
 
calculate::calculate(QWidget *parent) : QMainWindow(parent)
{
    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(".");
 
    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");
 
    QGridLayout *H=new QGridLayout(this); //声明了一个网格布局
 
    inputLine->setFixedHeight(50); //调整第一行宽度大小
    CEButton->setFixedHeight(50);
    ACButton->setFixedHeight(50);
 
    H->addWidget(inputLine,0,0,1,3);  //在(0,0)位置设置一行三列的区域
    H->setRowStretch(0,100);//设置行宽
    H->addWidget(CEButton,0,3);
    H->addWidget(ACButton,0,4);
 
    H->addWidget(sevenButton,1,0);
    H->addWidget(eightButton,1,1);
    H->addWidget(nineButton,1,2);
    H->addWidget(addButton,1,3);
    H->addWidget(subButton,1,4);
 
    H->addWidget(fourButton,2,0);
    H->addWidget(fiveButton,2,1);
    H->addWidget(sixButton,2,2);
    H->addWidget(mulButton,2,3);
    H->addWidget(divButton,2,4);
 
    H->addWidget(oneButton,3,0);
    H->addWidget(twoButton,3,1);
    H->addWidget(threeButton,3,2);
    H->addWidget(lefButton,3,3);
    H->addWidget(rigButton,3,4);
 
    H->addWidget(zeroButton,4,0);
    H->addWidget(decButton,4,1,1,2);
    H->addWidget(equButton,4,3,1,2);
 
    widget->setLayout(H); //将布局显示出来
 
    //数字输入
    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(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())); //等于号*/
 
}
void calculate::buttonZeroClicked()  //以下是实现相应的槽函数
{
    if(input=="0")
    input='0';
    else input=input+'0';
    inputLine->setText(input);
}
 
void calculate::buttonOneClicked()
{
    if(input=="0")
    input='1';
    else input=input+'1';
    inputLine->setText(input);
}
 
void calculate::buttonTwoClicked()
{
    if(input=="0")
    input='2';
    else input=input+'2';
    inputLine->setText(input);
}
 
void calculate::buttonThreeClicked()
{
    if(input=="0")
    input='3';
    else input=input+'3';
    inputLine->setText(input);
}
 
void calculate::buttonFourClicked()
{
    if(input=="0")
    input='4';
    else input=input+'4';
    inputLine->setText(input);
}
 
void calculate::buttonFiveClicked()
{
    if(input=="0")
    input='5';
    else input=input+'5';
    inputLine->setText(input);
}
 
void calculate::buttonSixClicked()
{
    if(input=="0")
    input='6';
    else input=input+'6';
    inputLine->setText(input);
}
 
void calculate::buttonSevenClicked()
{
    if(input=="0")
    input='7';
    else input=input+'7';
    inputLine->setText(input);
}
 
void calculate::buttonEightClicked()
{
    if(input=="0")
    input='8';
    else input=input+'8';
    inputLine->setText(input);
}
 
void calculate::buttonNineClicked()
{
    if(input=="0")
    input='9';
    else input=input+'9';
    inputLine->setText(input);
}
 
void calculate::buttonAddClicked()
{
    if(input=="0")
    input='+';
    else input=input+'+';
    inputLine->setText(input);
}
 
void calculate::buttonSubClicked()
{
    if(input=="0")
    input='-';
    else input=input+'-';
    inputLine->setText(input);
}
 
void calculate::buttonMulClicked()
{
    if(input=="0")
    input='*';
    else input=input+'*';
    inputLine->setText(input);
}
 
void calculate::buttonDivClicked()
{
    if(input=="0")
    input='/';
    else input=input+'/';
    inputLine->setText(input);
}
 
void calculate::buttonDecClicked() //小数点
{
    if(input=="0")
    input='.';
    else input=input+'.';
    inputLine->setText(input);
}
 
void calculate::buttonLefClicked()//左括号
{
    if(input=="0")
    input='(';
    else input=input+'(';
    inputLine->setText(input);
}
 
void calculate::buttonRigClicked()//右括号
{
    if(input=="0")
    input=')';
    else input=input+')';
    inputLine->setText(input);
}
 
void calculate::buttonCEClicked()
{
    input = input.left(input.length()-1); //减去一字符
    inputLine->setText(input);
}
void calculate::buttonACClicked() //直接清空
{
    input='0';
    inputLine->setText(input);
}
 
void calculate::buttonEquClicked()//等于号 ,输入等于号后开始运算,相当于原来的main
{
  std::string str=input.toStdString();
  const char *S=str.c_str();
  //QStack<double> Data;
  //QStack<char> Symb;
  double result;
  QString change;
  result=allocate(S); //数和运算符分类
  change=QString::number(result,10,6);
  //gcvt(result,10,change);
  input=input+"="+change;
  inputLine->setText(input);
}
 
double allocate(const char *num)
{
   QStack<double> Data;
   QStack<char> Symb;
    char   tnsarr[30]="0";//存放数字字符的临时字符串数组
    int    tnsarr_i=0;//存放数字字符的临时字符串数组的的下标
    int  i=0;
 
    while(i<strlen(num))
    {
        char c=num[i];
        if((c>='0'&&c<='9')||c=='.')//c是数字,放入tnsarr
        {
            tnsarr[tnsarr_i]=num[i];//分离出单个数字,字符串形式保存
            tnsarr_i++;//临时数组中字符数量
        }
        else//c不是数字
        {
            if(c!='('&&num[i-1]!=')')//c不是左括号,且c之前不是右括号,防止转化两次,多出零
            {
 
                Data.push(atof(tnsarr));//数字存入数据栈
                tnsarr_i=0;//分离数字重新计数
                memset(tnsarr,'\0',sizeof(tnsarr));//清空临时数组
            }
            Symb=check(c,&Data,Symb);//c 是运算符,进行运算符分类处理
        }
        i++;
    }
    if(num[i-1]>='0'&&num[i-1]<='9'&&num[i]=='\0')//解决最后一个数字无法录入问题
    {
        Data.push(atof(tnsarr));//数字存入数据栈
    }
 
    if(i==strlen(num))//字符已经遍历到最后
    {
        while(!Symb.empty())//计算符栈不是空的,说明栈顶向下运算符优先级递减。这应该是个循环的过程,保证计算所有的数
        {
           Symb=calcu(&Data,Symb);//取出Data栈顶向下两个数据,和Symb中栈顶运算符计算
        }
    }
    return Data.top();
}
//c不是数字,进行运算符分类处理
QStack<char> check(char c,QStack<double>* Data,QStack<char> Symb)
//void check(char c,QStack<double>& Data,QStack<char>& Symb)
{
    if(Symb.empty())//运算符栈为空
    {
        Symb.push(c);
        return Symb;
    }
    if(c=='(')//c是左括号,直接放入运算栈
        {
            Symb.push(c);
        }
    else if(c==')')//c是右括号,则进行运算
        {
            if(Symb.top()=='(')
            {
                Symb.pop();
            }
            else
            {
            Symb=calcu(Data,Symb);//取出Data栈顶向下两个数据,和Symb中栈顶运算符计算
            Symb=check(c,Data,Symb);//重新代入检测程序
            }
        }
    else//c不是括号
    {
        char sym=Symb.top();
        if(sym=='(')//当前栈顶运算sym符为‘(’
        {
            Symb.push(c);
        }
        else//当前栈顶运算符sym不是‘(’,不会是)括号,有括号不会存入Symb中
        {
            if(getPri(c)<=getPri(sym))//c的优先级小于等于Symb栈顶运算符sym
            {
                Symb=calcu(Data,Symb);//取出Data栈顶向下两个数据,和Symb中栈顶运算符计算
                Symb=check(c,Data,Symb);//Symb 栈顶下移后,重新比较c和栈顶运算符
            }
            else//c的优先级大于当前运算符栈栈顶运算符sym
            {
                Symb.push(c);// 运算符c压入Sym栈顶
            }
        }
    }
    return Symb;
}
 
//获得符号的优先性
int getPri(char c)
{
    switch(c)
    {
    case '+': return 0;    //如果是加减,返回0
    case '-': return 0;  //如果是加减,返回0
 
    case '*': return 1;   //如果是乘除,返回1
    case '/': return 1;  //如果是乘除,返回1
 
    default : break;
     }
}
 
//计算Data栈顶两个元素
QStack<char> calcu(QStack<double>* Data,QStack<char> Symb)
//void calcu(QStack<double>& Data,QStack<char>& Symb)
{
    float op1=0,op2=0;
 
    if(!Symb.empty())//非空
    {
        char c=Symb.pop();//取出运算符栈顶的运算符放入c//栈顶向下移一位
 
        //取出数据栈栈顶元素和栈顶下一位,栈顶向下两位
        op1=Data->pop();
        op2=Data->pop();
        //Data->top--;
 
        switch(c)
        {
        case'+':Data->push(op2+op1);break;
        case'-':Data->push(op2-op1);break;
        case'*':Data->push(op2*op1);break;
        case'/':Data->push(op2/op1);break;
        }
    }
    return Symb;
}
 
 
 
 
calculate::~calculate()
{
    
}
 

源文件:main.cpp

#include "calculate.h"
#include <QApplication>
 
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    calculate w;
    w.show();
    
    return a.exec();
}
 



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值