QT實現的簡單計算器

認識前綴、中綴、後綴表達式:


般我們平時用的計算式都是中綴表達式,因爲符號都是在操作數的中間的。相對應的符號在操作數後面的就叫後綴表達式(也稱逆波蘭式),符號在操作數前面的就叫前綴表達式(也稱波蘭式)

  • 爲什麼要把中綴表達式轉化爲後綴,前綴?


計算機沒法計算帶有括號,以及區分優先級的表達式,或者說很難計算。使用後綴,前綴,消除了括號和優先級。

  • 計算機如何計算後綴,前綴表達式?


計算後綴:從左到右遍歷後綴表達式,遇到操作數,放進棧,遇到操作符,棧頂兩個數出棧,進行運算,運算結果放進棧,直到讀完後綴表達式。

計算前綴:從左到右遍歷前綴表達式,遇到操作符,放進棧,遇到操作數,查看棧頂,棧頂爲操作符,放進棧,棧頂爲操作數,取出棧頂操作數和操作符,進行運算,運算後繼續判斷棧頂的情況。

  • 中綴表達式轉換成前綴表達式


(1)構建兩個棧,一個存運算符一個存操作數。運算符(以括號分界點)在棧內遵循越往棧頂優先級不降低的原則進行排列。

(2)從右至左掃描中綴表達式,從右邊第一個字符開始判斷:

  • 如果當前字符是數字,則分配到數字串的結尾並將數字串直接輸出。
  • 如果是運算符,則比較優先級。如果當前運算符的優先級大於等於棧頂運算符的優先級(當棧頂是括號時,直接入棧),則將運算符直接入棧;  否則將棧頂運算符出棧並輸出,直到當前運算符的優先級大於等於棧頂運算符的優先級(當棧頂是括號時,直接入棧),再將當前運算符入棧。
  • 如果是括號,則根據括號的方向進行處理。如果是右括號,則直接入棧;
  • 否則,遇右括號前將所有的運算符全部出棧並輸出,遇到右括號後將左右的兩括號一起刪除。

(3) 重複上述操作(2)直至掃描結束,將棧內剩餘運算符全部出棧並輸出,再逆綴輸出字符串。中綴表達式也就轉換爲前綴表達式了。

  • 中綴表達式轉換成後綴表達式:


和中綴表達式轉換成前綴表達式相似

思想: 

首先要知道中綴表達式如何轉換成後綴(前綴)表達式,中綴表達式是人容易理解的表達式,而對計算機來說,計算中綴表達式是很困難的。所以我們先把中綴表達式轉化成後綴表達式或者轉換成前綴表達式後在計算。

      中綴表達式是區分,由於不同的運算符間存在優先級,同一優先級的運算間又存在着運算結合問題。所以簡單地從左往右的計算是不可以的。而前綴和後綴表達式是不區分符號優先級的,且它們兩個沒有括號運算符。後綴表達式是從前面往後面讀,而前綴表達式的區別在於它是從後面往前面讀的。所

以我們一般是把中綴表達式轉換成後綴表達式來計算的。

      這裏我們用後綴表達式來講解。表達式轉換一般都是用到堆棧(簡稱“棧”),可以用順序棧或鏈式棧,這裏用順序棧進行講解,表達式轉換的過程中,遇到運算數就直接輸出,所以運算數的順序是不會改變的,改變的只是運算符的順序,所以表達式轉換是要用到符號棧來保存運算符的。

      應用棧將中綴表達式轉換成後綴表達式的基本過程爲:從頭到尾讀取中綴表達式的每個元素,運算規則分爲下列5種:

                    (1)遇到運算數直接輸出。

                    (2)遇到左括號直接將其壓棧。

                    (3)若遇到是的右括號,表明括號內的中綴表達式已經掃描完畢,將棧頂的運算符依次出棧,直至遇到左括號,然後把左括號也彈出,但不輸出(右括號是不入棧的)。

                    (4)遇到運算符,則與棧頂符號運算級對比,若當前運算符的運算級大於棧頂運算符的運算級,則入棧,而小於或等於都要先出棧,再把當前的運算符壓棧。

                    (5)若中綴表達式計算完成,則將棧中剩餘的運算符全部出棧。

        在上述處理的過程的一個關鍵是不同運算符優先級的設置,在程序實現中,可以用一個數字來代表運算符的優先級,優先級越高,數值越大,在這裏我是把左括號的優先級設爲1,加號和減號設爲2,乘號和除號設爲3,右括號設爲4(右括號可以不設置優先級)。

        而轉換成後綴表達式後,計算就比較簡單了。求值要用到一個數據棧來保存運算數,而在前面的遇到運算數就不該直接輸出了,而是遇到運算數就進數據棧,每當從符號棧出來一個符號,就要從數據棧中出兩個數據,並且進行運算。運算完成後再將結果壓入數據棧,直至表達式結束,而結束後,最後的計算結果就會棧數據棧中。

 C語言版代碼:

#include<stdio.h>
#include<stdlib.h>


/*數據棧*/
struct shuju {
    int data[100];
    int top;
};


/*符號棧*/ 
struct fuhao {
    char symbol[100];
    int top;
};


void InitOperateNum(struct shuju *StackNum)  
{
    StackNum->top = -1;
}


void InitOperateSymbol(struct fuhao *StackSymbol)  
{  
    StackSymbol->top = -1; 
}


/*存入數據棧*/
void Inshuju(struct shuju *StackNum, int num)
{
    StackNum->top ++;
    StackNum->data[StackNum->top] = num;
}


/*存入符號棧*/ 
void Infuhao(struct fuhao *StackSymbol, char ch)
{
    StackSymbol->top ++;
    StackSymbol->symbol[StackSymbol->top] = ch;
}


/*讀取數據棧*/
int Randshuju(struct shuju *StackNum)
{
    return StackNum->data[StackNum->top];
}


/*讀取符號棧*/
char Randfuhao(struct fuhao *StackSymbol)
{
    return StackSymbol->symbol[StackSymbol->top];
}


/*從數據棧取出數據*/
int Putshuju(struct shuju *StackNum)
{
    int x;
    x = StackNum->data[StackNum->top];
    StackNum->top --;
    return x;
}


/*從符號棧取出符號*/
char Putfuhao(struct fuhao *StackSymbol)
{
    char c;
    c = StackSymbol->symbol[StackSymbol->top];
    StackSymbol->top --;
    return c;
}


/*符號優先級判斷*/
int judge(char ch) {
    if(ch == '(') {
        return 1; 
    }
    if(ch == '+' || ch == '-') {
        return 2;
    }
    else if(ch == '*' || ch == '/') {
        return 3;
    }
    else if(ch == ')') {
        return 4;
    }
}


/*四則運算*/
int Math(int v1, int v2, char c)
{
    int sum;
    switch(c) {
        case '+' : {
            sum = v1 + v2;
            break;
        }
        case '-' : {
            sum = v1 - v2;
            break;
        }
        case '*' : {
            sum = v1 * v2;
            break;
        } 
        case '/' : {
            sum = v1 / v2;
            break;
        }
    }
    return sum;
}


int main()
{
    struct shuju data;
    struct fuhao symbol;
    InitOperateNum(&data);
    InitOperateSymbol(&symbol);
    int i, t, sum, v1, v2;
    char c;
    i = t = sum = 0;
    char v[100] = {0};
    char *str = (char *)malloc(sizeof(char)*200);
    while((c = getchar()) != '\n') {
        str[i] = c;
        i ++;
    }
    str[i] = '\0';
    for(i = 0; str[i] != '\0'; i ++) {
        if(i == 0 && str[i] == '-') {
            v[t++] = str[i];
        }
        else if(str[i] == '(' && str[i+1] == '-') {
            i ++;
            v[t++] = str[i++];
            while(str[i] >= '0' && str[i] <= '9') {
                v[t] = str[i];
                t ++;
                i ++;
            }
            Inshuju(&data, atoi(v));
            while(t > 0) {
                v[t] = 0;
                t --;
            }
            if(str[i] != ')') {
                i --;
                Infuhao(&symbol, '(');
            }
        }
        else if(str[i] >= '0' && str[i] <= '9') {
            while(str[i] >= '0' && str[i] <= '9') {
                v[t] = str[i];
                t ++;
                i ++;
            }
            Inshuju(&data, atoi(v));
            while(t > 0) {
                v[t] = 0;
                t --;
            }
            i --;
        }
        else {
            if(symbol.top == -1) {        //如果符號棧沒有元素,直接把符號放入符號棧 
                Infuhao(&symbol, str[i]);
            }
            else if(judge(str[i]) == 1) { //如果此符號是'(',直接放入符號棧 
                Infuhao(&symbol, str[i]);
            }
            else if(judge(str[i]) == 2) { //如果此符號是'+'或'-',判斷與棧頂符號是優先級 
                if(judge(Randfuhao(&symbol)) == 1) { //如果棧頂符號是'(',放入符號棧 
                    Infuhao(&symbol, str[i]);
                }
                else if(judge(Randfuhao(&symbol)) == 2) { //如果棧頂符號是'+'或'-',則出棧運算 
                    while(symbol.top >= 0 && data.top >= 1) { //循環出棧
                        v2 = Putshuju(&data);
                        v1 = Putshuju(&data);
                        sum = Math(v1, v2, Putfuhao(&symbol));
                        Inshuju(&data, sum); //將運算結果壓入數據棧 
                    }
                    Infuhao(&symbol, str[i]); //新符號進棧 
                }
                else if(judge(Randfuhao(&symbol)) == 3) { //如果棧頂符號是'*'或'/',則進符號棧 
                    while(symbol.top >= 0 && data.top >= 1) { //循環出棧
                        v2 = Putshuju(&data);
                        v1 = Putshuju(&data);
                        sum = Math(v1, v2, Putfuhao(&symbol));
                        Inshuju(&data, sum); //將運算結果壓入數據棧 
                    }
                    Infuhao(&symbol, str[i]); //新符號進棧 
                }
                /*棧頂符號不可能是')',故不做判斷*/ 
            }
            else if(judge(str[i]) == 3) { //如果此符號是'*'或'/',則判斷與棧頂符號是優先級
                if(judge(Randfuhao(&symbol)) == 1) { //如果棧頂符號是'(',放入符號棧 
                    Infuhao(&symbol, str[i]);
                }
                else if(judge(Randfuhao(&symbol)) == 2) { //如果棧頂符號是'+'或'-',則進符號棧
                    Infuhao(&symbol, str[i]); //新符號進棧
                }
                else if(judge(Randfuhao(&symbol)) == 3) { //如果棧頂符號是'*'或'/',則出棧運算 
                    while(symbol.top >= 0 && data.top >= 1) { //循環出棧
                        v2 = Putshuju(&data);
                        v1 = Putshuju(&data);
                        sum = Math(v1, v2, Putfuhao(&symbol));
                        Inshuju(&data, sum); //將運算結果壓入數據棧 
                    }
                    Infuhao(&symbol, str[i]); //新符號進棧
                }
            }
            else if(judge(str[i]) == 4) { // 如果棧頂符號是')',則出棧運算直到遇到'('
                do { //循環出棧直到遇到'('
                    v2 = Putshuju(&data);
                    v1 = Putshuju(&data);
                    sum = Math(v1, v2, Putfuhao(&symbol));
                    Inshuju(&data, sum); //將運算結果壓入數據棧 
                }while(judge(Randfuhao(&symbol)) != 1);
                Putfuhao(&symbol); //括號內運算結束後使'('出棧 
            }       
        }
    }
    free(str); //釋放內存空間
    while(symbol.top != -1) {
        v2 = Putshuju(&data);
        v1 = Putshuju(&data);
        sum = Math(v1, v2, Putfuhao(&symbol));
        Inshuju(&data, sum);    
    }
    printf("%d", data.data[0]);

    return 0;
}

 

問題記載:

問題一:

INVAILD USE OF INCOMPLETE type 'class MainWindow::QObject

這個真的是報了218行的錯誤,真的是可怕,修改方式,就把我的****.cpp文件裏面的    #include "ui_mainwindow.h"

剪切到了*****.h文件裏面

問題二:程序crashed

 

 

錯誤代碼如下:

#ifndef SYMBOL_STACK_H
#define SYMBOL_STACK_H
#include <QString>
typedef int data_type;
typedef QString symbol_type;

class symbol_stack
{
public:
    symbol_stack();
    symbol_type  push(symbol_type e);
    symbol_type  pop();
    symbol_type  clearstack();
    symbol_type  calculate (symbol_type popchar,symbol_type test_char);
    symbol_type  judge(char ch);
public:
    symbol_type *base = NULL;
    symbol_type *top = NULL ;
    int     stacksize ;
    symbol_type  test_char,popchar;
};

#endif // SYMBOL_STACK_H
#include "symbol_stack.h"
#include <iostream>
#include <QDebug>
#define   stack_init_size   100                           //棧的大小
#define   STAK_INCREASEMENT  1


symbol_stack::symbol_stack()
{
    base = ( symbol_type *)malloc( stack_init_size * sizeof( symbol_type));     //申請空間
    top = base ;                                             // top=base
    stacksize = stack_init_size;                             //設置棧的大小
    qDebug()<< "init the symbol stack ok !" << endl;
}


symbol_type   symbol_stack::push( symbol_type e)
{
    if( (top - base) >= stacksize )
    {
        base = ( symbol_type *)realloc( base, (stacksize + sizeof(e) ) * sizeof( symbol_type));
        if(!base)
            return "error";
    }
    *top = e;
    qDebug()<<"已存入符號棧中"<<top << " = "<< e <<endl;
    top++;
    return "ok";
}

symbol_type  symbol_stack::pop()
{
    symbol_type e;
    if(base ==top)
    {
        qDebug()<<"(symbol::pop):base = top "<< endl;
        return "error";
    }
    top--;
    e = *top;
    return e;
}

symbol_type  symbol_stack::clearstack()
{
    top = base ;
    base = ( symbol_type *)realloc(base,stack_init_size * sizeof( symbol_type))	;
    stacksize = 100 ;
    return "ok";
}

 

#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <QString>
typedef int data_type;
typedef QString symbol_type;

class DataStack
{
public:
    DataStack();
    data_type  push(data_type e);
    data_type  pop();
    data_type  clearstack();
    data_type  calculate (data_type  popchar,data_type test_char);
    data_type  judge(char ch);

public:
    data_type *base = NULL;
    data_type *top = NULL ;
    int     stacksize ;
    data_type  test_char,popchar;
};



#endif // STACK_H

 

#include "data_stack.h"
#include <QString>
#include <stdlib.h>
#include <cmath>
#include <time.h>
#include <QDebug>


#define   stack_init_size   100                            //棧的大小
#define   ok     10000
#define   error -10000
#define   STAK_INCREASEMENT  1


DataStack::DataStack()
{
    base = (data_type *)malloc( stack_init_size * sizeof(data_type));     //申請空間
    top = base;                                             // top=base
    stacksize = stack_init_size;                             //設置棧的大小
    qDebug() << "init the data stack ok !" << endl;
}

data_type  DataStack::push(data_type e)
{
    if( (top - base) >= stacksize )
    {
        base = (data_type *)realloc( base, (stacksize + STAK_INCREASEMENT ) * sizeof(data_type));
        //   stacksize += STAK_INCREASEMENT;
        if(!base)
            return -1;
    }
    *top = e;
    qDebug() << "已存入data棧中:" << top << " = " << e << endl;
    top ++;
    return ok;
}

data_type DataStack::pop()
{
    data_type e;
    if(base == top)
    {
        qDebug() << "空棧,沒有data" << endl;
        return -10000;
    }
    else
    {
        top--;
        e = *top;
        return e;
    }
}
data_type  DataStack::clearstack()
{
    top = base ;
    base = ( data_type *)realloc(base,stack_init_size * sizeof(data_type))	;
    stacksize = 100 ;
    return ok;
}
////////////////////////////////////////////////////////

修改方式:

把QString 類型改變成char 型。個人對於QString不怎麼了解。不明白QString 對象和變量的區別,我把它當做普通的變量使用,但是其實還有很多複雜的結構我不懂,所以每次需要讀取這個棧裏面的數據的時候,就會出現內存crashed,後來我把它變成了char類型,就可以成功運行了。

QT版本的代碼:

界面設計:

 

項目結構:

各個文件的內容如下,途中藍色的文件是我改變過名字的文件,所以當自己複製運行的時候,需要看清楚自己相應類的名字,所以會報編譯錯誤。

data_stack.h:

#ifndef STACK_H
#define STACK_H
#include <iostream>
#include <QString>
typedef double data_type;
typedef char symbol_type;

class DataStack
{
public:
    DataStack();
    data_type  push(data_type e);
    data_type  pop();
    data_type  clearstack();
    data_type  calculate (data_type  popchar,data_type test_char);
    data_type  judge(char ch);

public:
    data_type *base;
    data_type *top ;
    int     stacksize ;
    data_type  test_char,popchar;
};



#endif // STACK_H

model.h

#ifndef MODEL_H
#define MODEL_H


#include <QString>
#include "data_stack.h"
#define PI 3.14159265

class model
{
public:
    model();
    void set_num1(data_type num);
    void set_num2(data_type num);
    void set_flag(symbol_type  flag);
    data_type judge(symbol_type ch);
    data_type  doExpr();
public:
    data_type num1 ;
    data_type num2;
    symbol_type flag;
    data_type result;
};


#endif // MODEL_H

symbol_stack.h

#ifndef SYMBOL_STACK_H
#define SYMBOL_STACK_H
#include <QString>
typedef double data_type;
typedef char symbol_type;

class symbol_stack
{
public:
    symbol_stack();
    symbol_type  push(symbol_type e);
    symbol_type  pop();
    symbol_type  clearstack();
    symbol_type  calculate (symbol_type popchar,symbol_type test_char);
    symbol_type  judge(char ch);
public:
    symbol_type *base  ;
    symbol_type *top ;
    int     stacksize ;
    symbol_type  test_char,popchar;
};

#endif // SYMBOL_STACK_H

xuqionghua.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include "ui_mainwindow.h"
#include "model.h"
#include "symbol_stack.h"
#include <QString>
#include <stdio.h>
#include <math.h>



namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    void  data_callback();

private slots:
    void get_btn0();
    void get_btn1();
    void get_btn2();
    void get_btn3();
    void get_btn4();
    void get_btn5();
    void get_btn6();
    void get_btn7();
    void get_btn8();
    void get_btn9();
    void get_pointer();
    void get_btnadd();
    void get_btndivide();
    void get_dec();
    void get_btnmutip();
    void get_delete();
    void get_btn_equal();
    void get_btn_left();
    void get_btn_right();
    void get_btn_sin();
    void get_btn_cos();
    void get_btn_tan();
    void get_btn_cot();
//    void open();


private:
    QString temp,display;
    Ui::MainWindow *ui;
    model *model1 = new model();
    DataStack *data =new DataStack();
    symbol_stack  *symbol = new symbol_stack();
    data_type left_amount = 0;

};
#endif // MAINWINDOW_H

data_stack.cpp

#include "data_stack.h"
#include <QString>
#include <stdlib.h>
#include <cmath>
#include <time.h>
#include <QDebug>


#define   stack_init_size   100                            //棧的大小
#define   ok     10000
#define   error -10000
#define   STAK_INCREASEMENT  1


DataStack::DataStack()
{
    base = (data_type *)malloc( stack_init_size * sizeof(data_type));     //申請空間
    top = base;                                             // top=base
    stacksize = stack_init_size;                             //設置棧的大小
    qDebug() << "init the data stack ok !" << endl;
}

data_type  DataStack::push(data_type e)
{
    if( (top - base) >= stacksize )
    {
        base = (data_type *)realloc( base, (stacksize + STAK_INCREASEMENT ) * sizeof(data_type));
        //   stacksize += STAK_INCREASEMENT;
        if(!base)
            return -1;
    }
    *top = e;
    qDebug() << "已存入data棧中:" << top << " = " << e << endl;
    top ++;
    return ok;
}

data_type DataStack::pop()
{
    data_type e;
    if(base == top)
    {
        qDebug() << "空棧,沒有data" << endl;
        return -10000;
    }
    else
    {
        top--;
        e = *top;
        qDebug() << "take out :" << e << endl;
        return e;
    }
}
data_type  DataStack::clearstack()
{
    top = base ;
    base = ( data_type *)realloc(base,stack_init_size * sizeof(data_type))	;
    stacksize = 100 ;
    return ok;
}
////////////////////////////////////////////////////////

main.cpp

#include "xuqionghua.h"
#include <QApplication>
#include "model.h"
#include "symbol_stack.h"
#include "data_stack.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}


model.cpp

#include "model.h"
#include <QString>
#include <stdio.h>
#include <math.h>
#define PI 3.14159265


model::model()
{
    num1 = 0;
    num2 = 0;
    result= 0;
}
void model::set_num1(data_type num)
{
    this->num1 = num;
}
void model::set_num2(data_type num)
{
    this->num2 = num;
}
void model::set_flag(symbol_type flag)
{
    this->flag =flag;
}

data_type model::judge(symbol_type ch)
{
    if(ch == '(')
    {
        return 1;
    }
    if(ch == '+' || ch == '-')
    {
        return 2;
    }
    else if(ch == '*' || ch == '/')
    {
        return 3;
    }
    else if(ch == ')')
    {
        return 4;
    }
    else
        return -1;
}


data_type model::doExpr()
{
    if(flag == '+')
    {
        this->result = num1 + num2;
    }
    else if(flag =='-')
    {
        this->result = num1 - num2;
    }
    else if(flag == '*')
    {
        this->result = num1 * num2;
    }
    else if(flag == '/')
    {
        //        if(num2 == 0)
        //            return "ERROR";
        this->result = num1 / num2;
    }
    else if(flag == 's')
    {
        this->result  =  sin(num2*PI/180);
        num2 = this->result;
    }
    else if(flag == 'c')
    {
        this->result  = cos(num2*PI/180);
        num2 = this->result;
    }
    else if (flag == 't')
    {
        this->result  = tan(num2*PI/180);
        num2 = this->result;
    }
    else if(flag == 'o')
    {
        this->result  = 1/tan(num2*PI/180);
        num2 = this->result;
    }

    return this->result;

}

symbol_stack.cpp

#include "model.h"
#include <QString>
#include <stdio.h>
#include <math.h>
#define PI 3.14159265


model::model()
{
    num1 = 0;
    num2 = 0;
    result= 0;
}
void model::set_num1(data_type num)
{
    this->num1 = num;
}
void model::set_num2(data_type num)
{
    this->num2 = num;
}
void model::set_flag(symbol_type flag)
{
    this->flag =flag;
}

data_type model::judge(symbol_type ch)
{
    if(ch == '(')
    {
        return 1;
    }
    if(ch == '+' || ch == '-')
    {
        return 2;
    }
    else if(ch == '*' || ch == '/')
    {
        return 3;
    }
    else if(ch == ')')
    {
        return 4;
    }
    else
        return -1;
}


data_type model::doExpr()
{
    if(flag == '+')
    {
        this->result = num1 + num2;
    }
    else if(flag =='-')
    {
        this->result = num1 - num2;
    }
    else if(flag == '*')
    {
        this->result = num1 * num2;
    }
    else if(flag == '/')
    {
        //        if(num2 == 0)
        //            return "ERROR";
        this->result = num1 / num2;
    }
    else if(flag == 's')
    {
        this->result  =  sin(num2*PI/180);
        num2 = this->result;
    }
    else if(flag == 'c')
    {
        this->result  = cos(num2*PI/180);
        num2 = this->result;
    }
    else if (flag == 't')
    {
        this->result  = tan(num2*PI/180);
        num2 = this->result;
    }
    else if(flag == 'o')
    {
        this->result  = 1/tan(num2*PI/180);
        num2 = this->result;
    }

    return this->result;

}

xuqionghua..cpp

#include "xuqionghua.h"
#include "ui_mainwindow.h"

#include "model.h"
#include "QDebug"
#include <iostream>


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->model1 = new model;//
    this->temp = "";
    connect(this->ui->btn_0,SIGNAL(clicked(bool)),this,SLOT(get_btn0()));
    connect(this->ui->btn_1,SIGNAL(clicked(bool)),this,SLOT(get_btn1()));
    connect(this->ui->btn_2,SIGNAL(clicked(bool)),this,SLOT(get_btn2()));
    connect(this->ui->btn_3,SIGNAL(clicked(bool)),this,SLOT(get_btn3()));
    connect(this->ui->btn_4,SIGNAL(clicked(bool)),this,SLOT(get_btn4()));
    connect(this->ui->btn_5,SIGNAL(clicked(bool)),this,SLOT(get_btn5()));
    connect(this->ui->btn_6,SIGNAL(clicked(bool)),this,SLOT(get_btn6()));
    connect(this->ui->btn_7,SIGNAL(clicked(bool)),this,SLOT(get_btn7()));
    connect(this->ui->btn_8,SIGNAL(clicked(bool)),this,SLOT(get_btn8()));
    connect(this->ui->btn_9,SIGNAL(clicked(bool)),this,SLOT(get_btn9()));
    connect(this->ui->btn_pointer,SIGNAL(clicked(bool)),this,SLOT(get_pointer()));
    connect(this->ui->btn_add,SIGNAL(clicked(bool)),this,SLOT(get_btnadd()));
    connect(this->ui->btn_sub,SIGNAL(clicked(bool)),this,SLOT(get_dec()));
    connect(this->ui->btn_multiplication,SIGNAL(clicked(bool)),this,SLOT(get_btnmutip()));
    connect(this->ui->btn_division,SIGNAL(clicked(bool)),this,SLOT(get_btndivide()));
    connect(this->ui->btn_delete,SIGNAL(clicked(bool)),this,SLOT(get_delete()));
    connect(this->ui->btn_equal,SIGNAL(clicked(bool)),this,SLOT(get_btn_equal()));
    connect(this->ui->btn_left,SIGNAL(clicked(bool)),this,SLOT(get_btn_left()));
    connect(this->ui->btn_right,SIGNAL(clicked(bool)),this,SLOT(get_btn_right()));
    connect(this->ui->btn_sin,SIGNAL(clicked(bool)),this,SLOT(get_btn_sin()));
    connect(this->ui->btn_cos,SIGNAL(clicked(bool)),this,SLOT(get_btn_cos()));
    connect(this->ui->btn_tan,SIGNAL(clicked(bool)),this,SLOT(get_btn_tan()));
    connect(this->ui->btn_cot,SIGNAL(clicked(bool)),this,SLOT(get_btn_cot()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::get_btn0()
{
    this->temp += this->ui->btn_0->text();
    this->display += this->ui->btn_0->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}
void MainWindow::get_btn1()
{
    this->temp += this->ui->btn_1->text();
    this->display += this->ui->btn_1->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}
void MainWindow::get_btn2()
{
    this->temp += this->ui->btn_2->text();
    this->display += this->ui->btn_2->text();
    this->ui->lbl_display->setText(display);
}
void MainWindow::get_btn3()
{
    this->temp += this->ui->btn_3->text();
    this->display += this->ui->btn_3->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}


void MainWindow::get_btn4()
{
    this->temp += this->ui->btn_4->text();
    this->display += this->ui->btn_4->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}

void MainWindow::get_btn5()
{
    this->temp += this->ui->btn_5->text();
    this->display += this->ui->btn_5->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}

void MainWindow::get_btn6()
{
    this->temp += this->ui->btn_6->text();
    this->display += this->ui->btn_6->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}

void MainWindow::get_btn7()
{
    this->temp += this->ui->btn_7->text();
    this->display += this->ui->btn_7->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}

void MainWindow::get_btn8()
{
    this->temp += this->ui->btn_8->text();
    this->display += this->ui->btn_8->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}


void MainWindow::get_btn9()
{
    this->temp += this->ui->btn_9->text();
    this->display += this->ui->btn_9->text();
    this->ui->lbl_display->setText(display);
    this->ui->error_label->setText("");
}
void MainWindow::get_pointer()
{
    if(temp == "")
    {
        this->ui->error_label->setText("illegal input ");
    }
    else
    {
        this->temp += this->ui->btn_pointer->text();
        this->display += this->ui->btn_pointer->text();
        this->ui->lbl_display->setText(display);
        this->ui->error_label->setText("");
    }
}

void MainWindow::get_delete()
{
    //    this->temp = "";
    //    this->display = "";
    //    this->model1->set_flag("");
    this->model1->set_num1(0);
    this->model1->set_num2(0);
    this->ui->lbl_display->setText("0");
}
//   +-*/
void MainWindow::get_btnadd()
{
    data_type level1;
    data_type level2;
    data_type result;
    this->ui->error_label->setText("");
    if(temp == "")
    {
        this->ui->error_label->setText("illegal input ");
    }
    else
    {
        int num = temp.toFloat();
        data->push(num);
        data_callback();
        this->model1->result = num;
        this->temp = "";
        this->display += "+";
        this->ui->lbl_display->setText(display);
        this->temp = "";
        char symbol = this->symbol->pop();
        if(symbol == 'e')//error
        {
            this->symbol->push('+');
        }
        else
        {
            level1 = this->model1->judge( '+' );
            level2 = this->model1->judge( symbol );
            if(level2 == -1)
            {
                qDebug()<<" wrong symbol to compete" << endl;
            }
            else if(level1 <= level2)
            {
                data_type num;
                num = this->data->pop();
                this->model1->set_num2(num);
                num = this->data->pop();
                this->model1->set_num1(num);
                this->model1->flag = symbol;
                result = this->model1->doExpr();//calculate
                this->data->push(result);
                this->symbol->push('+');
            }
            else
            {
                this->symbol->push(symbol);
                this->symbol->push('+');
            }
        }
    }

}

void MainWindow::get_dec()
{
    data_type level1;
    data_type level2;
    data_type result;
    this->ui->error_label->setText("");
    if(temp == "")
    {
        this->ui->error_label->setText("illegal input ");
    }
    else
    {
        int num = temp.toFloat();
        data->push(num);
        data_callback();
        this->model1->result = num;
        this->temp = "";
        this->display += "-";
        this->ui->lbl_display->setText(display);
        this->temp = "";
        char symbol = this->symbol->pop();
        if(symbol == 'e')
        {
            this->symbol->push('-');
        }
        else
        {
            level1 = this->model1->judge('-');
            level2 = this->model1->judge(symbol);
            if(level2 == -1)
            {
                qDebug()<<" wrong symbol to compete" << endl;
            }
            else if(level1 <= level2)
            {
                data_type num;
                num = this->data->pop();
                this->model1->set_num2(num);
                num = this->data->pop();
                this->model1->set_num1(num);
                this->model1->flag = symbol;
                result = this->model1->doExpr();//calculate
                this->data->push(result);
                this->symbol->push('-');
            }
            else
            {
                this->symbol->push(symbol);
                this->symbol->push('-');
            }
        }
    }

}

void MainWindow::get_btnmutip()
{
    data_type level1;
    data_type level2;
    data_type result;
    this->ui->error_label->setText("");
    if(temp == "")
    {
        this->ui->error_label->setText("illegal input ");
    }
    else
    {
        int num = temp.toFloat();
        data->push(num);
        data_callback();
        this->model1->result = num;
        this->temp = "";
        this->display += "*";
        this->ui->lbl_display->setText(display);
        this->temp = "";
        char symbol = this->symbol->pop();
        if(symbol == 'e')
        {
            this->symbol->push('*');
        }
        else
        {
            level1 = this->model1->judge('*');
            level2 = this->model1->judge(symbol);
            if(level2 == -1)
            {
                qDebug()<<" wrong symbol to compete" << endl;
            }
            else if(level1 <= level2)
            {
                data_type num;
                num = this->data->pop();
                this->model1->set_num2(num);
                num = this->data->pop();
                this->model1->set_num1(num);
                this->model1->flag = symbol;
                result = this->model1->doExpr();//calculate
                this->data->push(result);
                this->symbol->push('*');
            }
            else
            {
                this->symbol->push(symbol);
                this->symbol->push('*');
            }
        }
    }
}

void MainWindow::get_btndivide()
{
    data_type level1;
    data_type level2;
    data_type result;
    if(temp == "")
    {
        this->ui->error_label->setText("illegal input ");
    }
    else
    {

        int num = temp.toFloat();
        data->push(num);
        data_callback();
        this->model1->result = num;
        this->temp = "";
        this->display += "/";
        this->ui->lbl_display->setText(display);
        this->temp = "";
        char symbol = this->symbol->pop();
        if(symbol == 'e')
        {
            this->symbol->push('/');
        }
        else
        {
            level1 = this->model1->judge('/');
            level2 = this->model1->judge(symbol);
            if(level2 == -1)
            {
                qDebug()<<" wrong symbol to compete" << endl;
            }
            else if(level1 <= level2)
            {
                data_type num;
                num = this->data->pop();
                this->model1->set_num2(num);
                num = this->data->pop();
                this->model1->set_num1(num);
                this->model1->flag = symbol;
                result = this->model1->doExpr();//calculate
                this->data->push(result);
                this->symbol->push('/');
            }
            else
            {
                this->symbol->push(symbol);
                this->symbol->push('/');
            }
        }
    }
}

void MainWindow::get_btn_equal()
{
    data_type num;
    symbol_type symbol;
    data_type result;
    this->ui->error_label->setText("");
    if(left_amount != 0)
    {
        this->ui->error_label->setText("錯誤表達式");
    }
    else
    {
        if(temp != "")
        {
            num = this->temp.toFloat();
            this->data->push(num);
            data_callback();
            this->model1->result = num;
        }
        while(1)//(num != -10000)&&(symbol != 'e')
        {
            num = this->data->pop();
            if(num == -10000 )
            {
                this->ui->error_label->setText("have no number to culater");
                this->model1->result = 0;
                result = 0;
                break;
            }
            else
            {
                this->model1->set_num2(num);
                result = this->model1->num2;
                symbol = this->symbol->pop();
                if(symbol == 'e')
                {
                    this->ui->error_label->setText("have no number to culater");
                    break;
                }
                else if(symbol == 's' || symbol == 'c' || symbol == 't' || symbol == 'o')
                {
                    num = this->model1->doExpr();

                }
                else
                {
                    this->symbol->push(symbol);
                }
                this->model1->result= result;
                num = this->data->pop();
                if(num == -10000 )
                {
                    this->ui->error_label->setText("have no number to culater");
                    break;
                }
                else
                {
                    this->model1->set_num1(num);
                    symbol = this->symbol->pop();
                    if(symbol == 'e' )
                    {
                        qDebug() << " symbol stack is  empty~";
                        break;
                    }
                    else
                    {
                        this->model1->set_flag(symbol);
                        this->model1->result = this->model1->doExpr();
                        this->data->push(this->model1->result);
                        result =this->model1->result;
                        qDebug() <<"this->model1->result:"<<this->model1->result << endl;
                    }
                }
            }
        }
    }
    //    }
    this->display += "=";
    this->display +=  QString::number(result);
    this->ui->lbl_display->setText(display);
    this->display = "";
    this->temp = "";
    this->model1->result = 0;
    this->data->clearstack();
    this->symbol->clearstack();

}
void MainWindow::get_btn_left()
{
    if(this->temp != "")
    {
        int  num  =  temp.toFloat();
        data->push(num);
    }
    QString ex = this->ui->btn_left->text();
    this->display += ex;
    symbol->push('(');
    left_amount++;
    this->ui->lbl_display->setText(display);
    this->temp = "";

}

void MainWindow::get_btn_right()
{
    char symbol;
    data_type result;
    if(left_amount == 0)
    {
        this->ui->error_label->setText("error,has no left bracket ");
    }
    else
    {
        if(temp != "")
        {
            int num = temp.toFloat();
            this->data ->push(num);
        }
        while(1)
        {
            symbol = this->symbol->pop();
            if(symbol  != '(')
            {
                data_type num;
                num = this->data->pop();
                this->model1->set_num2(num);
                num = this->data->pop();
                this->model1->set_num1(num);
                this->model1->flag = symbol;
                result = this->model1->doExpr();//calculate
                this->data ->push(result);
            }
            else
            {
                //                qDebug() << " take out (" << endl;
                break;
            }
        }
        this->left_amount--;
        this->display += ")";
        this->ui->lbl_display->setText(display);
        this->temp = "";
    }

}
void MainWindow::get_btn_sin()
{
    if(temp == "")
    {
        this->symbol->push('s');
        this->display += "sin";
        this->ui->lbl_display->setText(display);
    }
    else
    {
        this->ui->error_label->setText("error");
    }

}

void  MainWindow::get_btn_cos()
{
    if(temp == "")
    {
        this->symbol->push('c');
        this->display += "cos";
        this->ui->lbl_display->setText(display);
    }
    else
    {
        this->ui->error_label->setText("error");
    }

}

void  MainWindow::get_btn_tan()
{
    if(temp == "")
    {
        this->symbol->push('t');
        this->display += "tan";
        this->ui->lbl_display->setText(display);
    }
    else
    {
        this->ui->error_label->setText("error");
    }

}

void  MainWindow::get_btn_cot()
{
    if(temp == "")
    {
        this->symbol->push('o');
        this->display += "cot";
        this->ui->lbl_display->setText(display);
    }
    else
    {
        this->ui->error_label->setText("error");
    }

}


void MainWindow::data_callback()
{
    symbol_type symbol;
    data_type num;
    symbol = this->symbol->pop();
    num = this->data->pop();
    this->model1->set_num2(num);
    if(symbol == 's' || symbol == 'c' || symbol == 't' || symbol == 'o' ||symbol =='e')
    {
        if(symbol == 's')
        {
            this->model1->set_flag('s');
            num = this->model1->doExpr();
            this->data->push(num);
        }
        else if(symbol == 'c')
        {
            this->model1->set_flag('c');
            num = this->model1->doExpr();
            this->data->push(num);
        }
        else if(symbol == 't')
        {
            this->model1->set_flag('t');
            num= this->model1->doExpr();
            this->data->push(num);
        }
        else if(symbol == 'o')
        {
            this->model1->set_flag('o');
            num =this->model1->doExpr();
            this->data->push(num);
        }
        else
        {
            qDebug() <<" error,empty symbol stack ";
            this->data->push(num);
        }
    }
    else
    {
        this->symbol->push(symbol);
        this->data->push(num);
    }
    //    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章