赞
踩
设计一个支持连续计算的科学计算器。通过单击按钮,或者从文本框输入运算表达式,并完成计算,并且将结果显示出来。例如4*5+3,3+2/3,n的阶乘,x的y次幂,开平方,三角函数,log,ln,清除后退,显示历史记录等等。
进行输入时直接输入到显示框上,当按下“=”按钮时读取显示框里的表达式,进行计算,并将结果输出到显示屏上。所以,计算器的核心算法就在于如何计算从显示屏上读取的中缀表达式。
计算中缀表达式需要用到两个栈Stack,一个作为数字栈number_stack,专门存储中缀表达式里面的数字,另一个是操作符栈operator_stack,用来存储操作符。核心算法是中缀表达式转成后缀表达式,然后计算后缀表达式,但是这俩个可以合起来一块计算。具体算法流程如下:
首先对涉及到的操作符设置优先级。从左至右依次读取中缀表达式,如果是数字(直接读出负数、小数、多于十位的数)则直接压入数字栈number_stack。如果是操作符(不包括左右括号),观察operator_stack是否为空,为空则直接压入栈,不为空则比较当前栈顶与此操作符的优先级。若此操作符优先级高则直接压入栈,否则弹出栈顶,并从数字栈number_stack弹出两个数字,第一个弹出的数字作为右操作数,第二个弹出的作为左操作数,与操作符运算并将结果压入栈。(若弹出的操作符为单目运算符,则只弹出一个数字)
如果碰到“(”直接入栈,碰到“)”从操作符栈operator_stack一直弹出,直到弹出“(”。到中缀表达式读取完后,看操作符栈operator_stack是否为空,不为空就依次弹出栈,直到为空。此时数字栈
number_satck剩余的一个数就是结果,将结果输出到显示屏上。
下面为流程图:
calculate.h
#ifndef CALCULATE_H #define CALCULATE_H #include<iostream> #include<string> #include<stack> #include<math.h> using namespace std; class calculate { public: calculate(); }; extern bool is_new; extern bool is_minus; extern double ans; extern double e; int getPriority(char ch);//得到运算符的优先级 void calculate(stack<double> &mystack, char operation);//根据操作符进行计算 double calculator(string str);//遍历表达式 #endif // CALCULATE_H
calculate.cpp
#include "calculate.h" #include<iostream> #include<string> #include<stack> #include<math.h> using namespace std; calculate::calculate() { } bool is_new = false; bool is_minus = false; double ans = 0; double e = 2.718281828459045; double P = 3.14159265358979323846; int getPriority(char ch)//得到运算符优先级 { if (ch == '+' || ch == '-') return 1; else if (ch == '*' || ch == '/') return 2; else if (ch == 's' || ch == 'c'|| ch == 't' || ch == 'i' || ch == 'o' || ch == 'a' || ch == '^' || ch == 'g' || ch == 'n' || ch == 'r' || ch == 'm') return 3; else if (ch == '!') return 4; else return 5; } void calculate(stack<double> &number, char tmp_operation)//运算符计算函数 { double num1, num2, num3; num2 = number.top(); number.pop(); if(tmp_operation == '!'){ num3 = 1; while(num2>1){ num3 *= num2; num2 --; } } else if(tmp_operation == 's' || tmp_operation == 'c' || tmp_operation == 't' || tmp_operation == 'i' || tmp_operation == 'o' || tmp_operation == 'a' || tmp_operation == 'g' || tmp_operation == 'n' || tmp_operation == 'r'){ if(tmp_operation == 's')num3 = sin(num2); else if(tmp_operation == 'c')num3 = cos(num2); else if(tmp_operation == 't')num3 = tan(num2); else if(tmp_operation == 'i')num3 = asin(num2); else if(tmp_operation == 'o')num3 = acos(num2); else if(tmp_operation == 'a')num3 = atan(num2); else if(tmp_operation == 'g')num3 = log10(num2); else if(tmp_operation == 'n')num3 = log(num2); else if(tmp_operation == 'r')num3 = sqrt(num2); } else{ num1 = number.top(); number.pop(); if (tmp_operation == '+') { num3 = num1 + num2; } else if (tmp_operation == '-') { num3 = num1 - num2; } else if (tmp_operation == '*') { num3 = num1 * num2; } else if (tmp_operation == '/') { num3 = num1 / num2; } else if (tmp_operation == '^') { num3 = pow(num1, num2); } else if (tmp_operation == 'm'){ num3 = fmodf(num1, num2); } } number.push(num3); } double calculator(string str)//遍历表达式 { stack<double> number; stack<char> operation; int i = 0, j; int size = str.size(); char tmp_operation; string num; string num0; while (i < size) { if (str[i] >= '0' && str[i] <= '9') { j = i; while ((j < size && str[j] >= '0' && str[j] <= '9') || str[j]=='.') { j++; } num = str.substr(i, j - i); if(!is_minus) number.push(atof(num.c_str())); else number.push(0-atof(num.c_str())); i = j; } else if (str[i] == 'A'){ number.push(ans); i+=3; } else if(str[i] == 'e'){ number.push(e); i++; } else if(str[i] == 'P'){ number.push(P); i+=2; } else if(str[i] == '(' || str[i] == ')'){ if (str[i] == '(') operation.push(str[i]); else { while (operation.top() != '(') { tmp_operation = operation.top(); operation.pop(); calculate(number, tmp_operation); } operation.pop(); } i++; } else if(str[i] == 's' || str[i] == 'c' || str[i] == 't'){ if(str[i] == 's' && str[i+1] == 'q'){ operation.push('r'); i += 4; } else{ operation.push(str[i]); i += 3; } } else if(str[i] == 'a'){ if(str[i+3]=='s')operation.push('i'); else if(str[i+3]=='c')operation.push('o'); else if(str[i+3]=='t')operation.push('a'); i += 6; } else if(str[i] == 'l'){ if(str[i+1] == 'o'){operation.push('g');i+=3;} else if(str[i+1]=='n'){operation.push('n');i+=2;} } else{ if(str[i]=='-' && (operation.empty() || operation.top()=='(')){ is_minus = true; } else if (operation.empty()) { operation.push(str[i]); } else { while (!operation.empty()) { tmp_operation = operation.top(); if (getPriority(tmp_operation) >= getPriority(str[i])) { operation.pop(); calculate(number, tmp_operation); } else break; } operation.push(str[i]); } if(str[i] == 'm')i += 3; else i++; } } while (!operation.empty()) { tmp_operation = operation.top(); operation.pop(); calculate(number, tmp_operation); } return number.top(); }
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include<calculate.h> QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACE class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private slots: void on_pushButton_mul_clicked(); void on_pushButton_div_clicked(); void on_pushButton_sub_clicked(); void on_pushButton_add_clicked(); void on_pushButton_pow_clicked(); void on_pushButton_point_clicked(); void on_pushButton_0_clicked(); void on_pushButton_1_clicked(); void on_pushButton_2_clicked(); void on_pushButton_3_clicked(); void on_pushButton_4_clicked(); void on_pushButton_5_clicked(); void on_pushButton_6_clicked(); void on_pushButton_7_clicked(); void on_pushButton_8_clicked(); void on_pushButton_9_clicked(); void on_pushButton_del_clicked(); void on_pushButton_AC_clicked(); void on_pushButton_equ_clicked(); void on_pushButton_Ans_clicked(); void on_pushButton_left_clicked(); void on_pushButton_right_clicked(); void on_pushButton_pi_clicked(); void on_pushButton_sin_clicked(); void on_pushButton_cos_clicked(); void on_pushButton_tan_clicked(); void on_pushButton_1x_clicked(); void on_pushButton_n1_clicked(); void on_pushButton_squ_clicked(); void on_pushButton_e_clicked(); void on_pushButton_arcsin_clicked(); void on_pushButton_arccos_clicked(); void on_pushButton_arctan_clicked(); void on_pushButton_log_clicked(); void on_pushButton_ln_clicked(); void on_pushButton_x2_clicked(); void on_pushButton_x3_clicked(); void on_pushButton_ex_clicked(); void on_pushButton_2x_clicked(); void on_pushButton_mod_clicked(); void on_pushButton_clicked(); private: Ui::Widget *ui; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" #include<QDebug> #include<QLineEdit> #include<QString> #include<QByteArray> #include<stdlib.h> #include"calculate.h" Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) { ui->setupUi(this); connect(ui->line, SIGNAL(editingFinished()), this, SLOT(on_pushButton_equ_clicked())); QFont font; font.setPointSize(16); ui->line->setFont(font); } Widget::~Widget() { delete ui; } void Widget::on_pushButton_equ_clicked() { string str = ui->line->text().toStdString(); ans = calculator(str); ui->line->setText(QString::number(ans)); is_new = true; ui->textEdit->append(QString::fromStdString(str) + "=" + QString::number(ans)); } void Widget::on_pushButton_del_clicked() { if(is_new){ui->line->setText("");} QString a = ui->line->text(); if(a.right(6)=="arcsin" || a.right(6)=="arccos" || a.right(6)=="arctan") a.chop(6); else if(a.right(3)=="sin" || a.right(3)=="cos" || a.right(3)=="tan" || a.right(3)=="Ans" || a.right(3)=="mod" || a.right(3)=="log") a.chop(3); else if(a.right(4)=="sqrt") a.chop(4); else if(a.right(2)=="ln" || a.right(2)=="PI") a.chop(2); else a.chop(1); ui->line->setText(a); is_new = false; } void Widget::on_pushButton_mul_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'*'); is_new = false; } void Widget::on_pushButton_div_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'/'); is_new = false; } void Widget::on_pushButton_sub_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'-'); is_new = false; } void Widget::on_pushButton_add_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'+'); is_new = false; } void Widget::on_pushButton_pow_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'^'); is_new = false; } void Widget::on_pushButton_point_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'.'); is_new = false; } void Widget::on_pushButton_0_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'0'); is_new = false; } void Widget::on_pushButton_1_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'1'); is_new = false; } void Widget::on_pushButton_2_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'2'); is_new = false; } void Widget::on_pushButton_3_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'3'); is_new = false; } void Widget::on_pushButton_4_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'4'); is_new = false; } void Widget::on_pushButton_5_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'5'); is_new = false; } void Widget::on_pushButton_6_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'6'); is_new = false; } void Widget::on_pushButton_7_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'7'); is_new = false; } void Widget::on_pushButton_8_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'8'); is_new = false; } void Widget::on_pushButton_9_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'9'); is_new = false; } void Widget::on_pushButton_AC_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(""); is_new = false; } void Widget::on_pushButton_Ans_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +"Ans"); is_new = false; } void Widget::on_pushButton_left_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +'('); is_new = false; } void Widget::on_pushButton_right_clicked() { if(is_new){ui->line->setText("");} ui->line->setText(ui->line->text() +')'); is_new = false; } void Widget::on_pushButton_pi_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"PI"); } void Widget::on_pushButton_sin_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"sin"); } void Widget::on_pushButton_cos_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"cos"); } void Widget::on_pushButton_tan_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"tan"); } void Widget::on_pushButton_1x_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"1/"); } void Widget::on_pushButton_n1_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"!"); } void Widget::on_pushButton_squ_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"sqrt"); } void Widget::on_pushButton_e_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +'e'); } void Widget::on_pushButton_arcsin_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"arcsin"); } void Widget::on_pushButton_arccos_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"arccos"); } void Widget::on_pushButton_arctan_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"arctan"); } void Widget::on_pushButton_log_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"log"); } void Widget::on_pushButton_ln_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"ln"); } void Widget::on_pushButton_x2_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"^2"); } void Widget::on_pushButton_x3_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"^3"); } void Widget::on_pushButton_ex_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"e^"); } void Widget::on_pushButton_2x_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"2^"); } void Widget::on_pushButton_mod_clicked() { if(is_new){ui->line->setText("");} is_new = false; ui->line->setText(ui->line->text() +"mod"); } void Widget::on_pushButton_clicked() { ui->textEdit->setText(""); }
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。