Qt實現(xiàn)可以計算大數(shù)的簡單計算器
1、簡介
計算器是我們生活中很常見的東西,它可以由多種語言多種方式來實現(xiàn),今天我想講的是基于C++語言,由QT實現(xiàn)的可以計算大數(shù)的簡單計算器。
2、作品演示
(1)簡單四則運算
(2)大數(shù)運算
3、重點原理講解
(1)四則運算如何實現(xiàn) (2)大數(shù)的加減乘除
4、代碼主體框架
1個主函數(shù); 兩個類: 一個calculator類,實現(xiàn)了對界面的布局,其實這個布局很簡單,就設置了一些按鈕以及一個顯示框。
類的聲明:
class calculator : public QMainWindow { Q_OBJECT public: calculator(QWidget *parent = 0); ~calculator(); 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; QPushButton *addButton; QPushButton *subButton; QPushButton *divButton; QPushButton *mulButton; QPushButton *equButton; QPushButton *timButton; //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 buttonTimClicked(); //時間 void buttonDecClicked();//小數(shù)點 void buttonBotClicked(); //加減號 void buttonEquClicked();//等于號 void buttonLefClicked();//左括號 void buttonRigClicked();//右括號 void buttonCEClicked();//CE void buttonACClicked();//AC };
界面布局:
calculator::calculator(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("."); botButton=new QPushButton("±"); timButton=new QPushButton("Time"); 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); //聲明了一個網(wǎng)格布局 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(timButton,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); widget->setLayout(H); //將布局顯示出來 connect(zeroButton,SIGNAL(clicked()),this,SLOT(buttonZeroClicked()));//信號與槽函數(shù) 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(timButton,SIGNAL(clicked(bool)),this,SLOT(buttonTimClicked()));//時間 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())); //等于號*/ }
槽函數(shù)實現(xiàn)部分舉例說明,其它類似:
void calculator::buttonZeroClicked() //以下是實現(xiàn)相應的槽函數(shù) { if(input=="0") input='0'; else input=input+'0'; inputLine->setText(input); } void calculator::buttonTimClicked() //Time { input=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz"); //格式化輸出當前時間 inputLine->setText(input); }
點擊等于號的時候調用Change函數(shù)和Exchange函數(shù),對式子進行運算。
Change 函數(shù),將顯示框里面的中綴表達式轉化為了后綴表達式,存入OPS字符數(shù)組中,數(shù)字之間用#分開,保存數(shù)組長度,方便后面的運算。
Exchange函數(shù),將后綴表達式進行運算,對每兩個數(shù)的加法減法乘法或者除法都是采用大數(shù)運算,通過CDashu類對 + – * / 的重載,然后在Exchange 函數(shù)中建立對象調用,最后將返回值再轉化為字符輸出到屏幕上。
void calculator::buttonEquClicked()//等于號 { std::string str=input.toStdString(); const char *S=str.c_str(); cout<<S[strlen(S)]; char OPS[max1]; int len; double result; char* change = new char[max1]; bool flag; Change(S,OPS,len); change = EXchange(OPS,len,result,flag); //QString::number(result,10,6); input=input+"="+change; inputLine->setText(input); } int Change(const char *S,char OPS[],int &len) { QStack<char> OPE; int i = 0 ,j = 0; int l = strlen(S); for( i ;i < strlen(S);i++) { switch(S[i]) { case '+': if(OPE.isEmpty()) OPE.push(S[i]); else if(OPE.top() == '*' || OPE.top() == '/' || OPE.top() == '-') { OPS[j++] = OPE.pop(); i--;//多次判斷OPE.top()符號的優(yōu)先級是否高于'+' } else OPE.push(S[i]); break; case '-': //if('('!=S[i-1]&&0!=i) //{ if(OPE.isEmpty()) OPE.push(S[i]); else if(OPE.top() == '*' || OPE.top() == '/' || OPE.top() == '+') { OPS[j++] = OPE.pop(); i--; } else OPE.push(S[i]); break; //} /*else { while ((S[i] >= '0'&&S[i] <= '9' )|| S[i] == '.'||('-'==S[i]&&(S[i-1]<'0'||S[i-1]>'9' || i == 0))) { if(S[i] == '-') OPS[j++]='#'; OPS[j++] = S[i]; i++; } i--; OPS[j++] = '#'; //數(shù)字中的間隔符 }*/ case '*': if(OPE.isEmpty()) { OPE.push(S[i]); } else if(OPE.top() == '/') { OPS[j++] = OPE.pop(); i--; } else OPE.push(S[i]); break; case '/': if(OPE.isEmpty()) { OPE.push(S[i]); } else if(OPE.top() == '*') { OPS[j++] = OPE.pop(); i--; } else OPE.push(S[i]); break; case'(': OPE.push(S[i]); break; case')': while (OPE.top() != '(') { OPS[j++] = OPE.pop();//遇到右括號,一直彈出操作符知道遇到左括號 } OPE.pop();//直接不放入數(shù)組彈出左括號 break; default: while (S[i] >= '0'&&S[i] <= '9' || S[i] == '.'||('-'==S[i]&&S[i-1]<'0'&&S[i-1]>'9')) { OPS[j++] = S[i]; i++; } i--; OPS[j++] = '#'; //數(shù)字中的間隔符 break; }//switch }//for while (!OPE.isEmpty()) { OPS[j++] = OPE.pop(); } len = j; return 0; }//Change char* EXchange(char OPS[], int len, double &result,bool &flag) { int tag = 0,t3; QStack<char*> SZ; char *s = new char[max1]; char *str1 = new char[max1]; char *str2 = new char[max1]; char *str = new char[max1]; char st1[max1][max1]; CDashu x1; CDashu x2; CDashu y; int i,j,t = 0,temp; for(i = 0;i < len;i++) { switch(OPS[i]) { case '+': str1 = SZ.pop(); str2 = SZ.pop(); x1.Change(str1); x2.Change(str2); y = x2 + x1; tag = 0; temp = 0; if(y.a[0]) { s[tag] = y.a[0]+'0'; tag++; } else temp++; for( ;tag <= y.getlength()-temp;tag++) { s[tag] = y.a[tag + temp]+'0'; } s[tag] = '\0'; SZ.push(s); break; case '-': str1 = SZ.pop(); str2 = SZ.pop(); x1.Change(str1); x2.Change(str2); y = x2 - x1; tag = 0; temp = 0; if(y.getflag()) { s[tag] = '-'; tag++; } if(y.a[0]) { s[tag] = y.a[0]+'0'; tag++; } else temp++; if(s[0] == '-') { for( ;tag <= y.getlength();tag++) { s[tag] = y.a[tag]+'0'; } s[tag] = '\0'; } else { for( ;tag <= y.getlength()-temp;tag++) { s[tag] = y.a[tag + temp]+'0'; } s[tag] = '\0'; } SZ.push(s); break; case '*': int max,min,max2; str1 = SZ.pop(); str2 = SZ.pop(); x1.Change(str1); x2.Change(str2); y = x1*x2; y.get(max,max2,min); j = 0; for(t3 = max;t3 >= min;t3--) { s[j++] = y.a[t3]+'0'; } s[j] = '\0'; SZ.push(s); break; case '/': { str1 = SZ.pop(); str2 = SZ.pop(); x1.Change(str1); x2.Change(str2); y = x2 / x1; int x = 0; i = 0; int num[max1]; while(y.yushu[0]) { num[x] = y.yushu[0]%10; y.yushu[0] = y.yushu[0]/10; x++; } x--; while(x > -1) { s[i] = num[x]+'0'; x--; i++; } s[i] = '.'; for(i = i+1,j = 1;j < 50;i++,j++) { s[i] = y.yushu[j]+'0'; } s[i] = '\0'; SZ.push(s); } break; default: j = 0; while (OPS[i] != '#') { st1[t][j] = OPS[i]; j++; i++; } st1[t][j] = '\0'; SZ.push(st1[t]); t++; break; } } return SZ.top(); }
下面重點介紹一下大數(shù)類:
類的聲明與部分成員函數(shù)的實現(xiàn)
#ifndef CDASHU_H #define CDASHU_H #include<cstring> using namespace std; #define max1 500 #define MAXN 9999 class CDashu { public: int a[max1]; int yushu[max1]; CDashu() { length = 1; memset(a, 0, sizeof(a)); } //構造函數(shù) void Change( char *s); //將字符串轉換為大數(shù) long getlength() { return length; } int getflag() { return flag; } friend int Compare(CDashu a,CDashu b); void get(int &m,int &m2,int &min) { m = max; m2 = max2; min = this->min; } ~CDashu(); CDashu operator +(CDashu b);//對各類運算的重載 CDashu operator -(CDashu b); CDashu operator *(CDashu b); CDashu operator /(CDashu b); private: long length; int flag; int max,min,max2; }; #endif // CDASHU_H
大數(shù)類的實現(xiàn):
#include "cdashu.h" #include "cdashu.h" #include <iostream> #include <string.h> using namespace std; /* ostream& operator<<(ostream& out, CDashu& b) //重載輸出運算符 { int i; out << b.a[b.length - 1]; for (i = b.length - 2; i >= 0; i--) { out.width(4); out.fill('0'); out << b.a[i]; } return out; }*/ void CDashu::Change( char *s) { memset(a, 0, sizeof(a)); long l = strlen(s); length = l; for (int i = 1; i <= l; i++) { a[i] = (int)s[i-1] - '0'; } for (int i = 1; i <= l; i++) { cout << a[i]; } cout << endl; } CDashu CDashu::operator+(CDashu b) { int i = length, j = b.length; if (i >= j) { for (; i > 0 && j > 0; i--, j--) a[i] += b.a[j];//逐個相加 i = length; for (i; i >= 0; i--) { if (a[i] >= 10) //進位運算 { a[i - 1] += a[i] / 10; a[i] %= 10; } } return *this; } else { for (; i >= 0 && j >= 0; i--, j--) b.a[j] += a[i];//逐個相加 i = b.length; for (i; i > 0; i--) { if (b.a[i] >= 10) //進位運算 { b.a[i - 1] += b.a[i] / 10; b.a[i] %= 10; } } return b; } } CDashu CDashu::operator -(CDashu b) { flag = 0; b.flag = 0; int i, j; if (length == b.length) { i = 1;j = 1; while (a[i] == b.a[i]) { i++; } if (a[i] < b.a[i]) b.flag = 1; } i = length; j = b.length; if (i < j || b.flag) { for (i; i > 0 && j > 0; i--, j--) b.a[j] -= a[i];//一一相減 i = b.length; for (i; i > 0; i--) { if (b.a[i] < 0) //補位運算 { b.a[i] += 10; b.a[i - 1] -= 1; } } return b; } else { for (i; i >= 0 && j >= 0; i--, j--) a[i] -= b.a[j];//一一相減 i = length; for (i; i >= 0; i--) { if (a[i] < 0) //補位運算 { a[i] += 10; a[i - 1] -= 1; } } return *this; } cout << endl; } CDashu CDashu::operator *(CDashu b) { CDashu t; int i, j; t.max = t.min = t.max2 = 1; for (i = length; i > 0; i--) { for (j = b.length; j > 0; j--) { t.a[length+b.length+1 -(i + j)] += a[i] * b.a[j];//t.a[]初始化為0 t.min = min<(length+b.length+1 -(i + j))?t.min:(length+b.length+1 -(i + j)); t.max = max>(length+b.length+1 -(i + j))?t.max:(length+b.length+1 -(i + j)); } } for (i = t.min; i <= t.max; i++) { if (t.a[i] >= 10) { t.a[i + 1] += t.a[i] / 10; t.a[i] = t.a[i] % 10; t.max2 = i+1; } } t.max = t.max > t.max2 ? t.max:t.max2; return t; } CDashu CDashu::operator /(CDashu b) { int i,j,flag = 1,count = 0,tag = 0,mm=0; min = 1; flag = Compare(*this,b); max = length; if (length < b.length || flag == 0) count = 0; else { while (flag == 1 || flag == 2) { if(min == length && a[min] == 0) { break; } else { i = length; j = b.length; count++; for ( ; i >= min && j > 0; i--, j--) a[i] -= b.a[j];//一一相減 i = length; for (i; i >= min; i--) { if (a[i] < 0) //補位運算 { a[i] += 10; a[i - 1] -= 1; } } i = min; if (a[i] == 0 && i != length) { while (a[i] == 0) { i++; } min = i; }//如果有減到前面為0,最小下標右移到不為0的位置 flag = Compare(*this,b);//比較兩個數(shù)的大小 } cout<<count<<endl; }//while }//else cout << count << '.'; yushu[0] = count; tag = 0; for(i = 1;i <= length;i++) { if(a[i] != 0) { tag = 1; break; } } if(!tag) { for(i = 1;i < 50;i++) { yushu[i] = 0; } } else { int jingdu = 1; while(jingdu < 50) { count = 0; /*if(min == length && a[min] == 0) { for( ;jingdu < 30;jingdu++) { yushu[jingdu] = 0; } break; }*/ length++; a[length] = 0; flag = Compare(*this,b);//比較兩個數(shù)的大小 if(flag == 2) { yushu[jingdu] = 1; jingdu++; for( ; jingdu < 50;jingdu++) { yushu[jingdu] = 0; } } else { if (flag == 0) { yushu[jingdu] = 0; jingdu++; } else { while (flag == 1 || flag==2) { if(min == length && a[min] == 0) { mm = 1; yushu[jingdu] = count; for( jingdu = jingdu+1;jingdu < 50;jingdu++) { yushu[jingdu] = 0; } break; } count++; i = length,j = b.length; for(;i >= min && j > 0;i--,j--) { a[i] -= b.a[j]; } i = length; for (i; i >= min; i--) { if (a[i] < 0) //補位運算 { a[i] += 10; a[i - 1] -= 1; } } i = min; if (a[i] == 0 && i != length) { while(a[i] == 0) { i++; } } min = i;//如果有減到前面為0,最小下標右移到不為0的位置 flag = Compare(*this,b);//比較兩個數(shù)的大小 } yushu[jingdu] = count; jingdu++; } } if(mm) break; } } return *this; } int Compare(CDashu a,CDashu b) { int i = a.min, j = 1,flag = 1; if(a.length-a.min + 1 < b.length) flag = 0; else if(a.length-a.min+1 > b.length) flag = 1; else { while (a.a[i] == b.a[j] && i <= a.length && j <= b.length) { i++; j++; } if (a.a[i] < b.a[j]) flag = 0; if(a.a[i] == b.a[i]) { flag = 2; } } return flag; } CDashu::~CDashu() { }
到此這篇關于Qt實現(xiàn)可以計算大數(shù)的簡單計算器的文章就介紹到這了,更多相關Qt計算器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
C語言如何求整數(shù)的位數(shù)及各位數(shù)字之和
這篇文章主要介紹了C語言如何求整數(shù)的位數(shù)及各位數(shù)字之和,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-11-11