大作业题目:高性能计算器
使用C++语言设计一个高性能计算器,具有以下功能: (1)基本功能(80分)(i)在控制台下输入一个表达式,例如,输入 3+5*4,可以按输入的表达式中的运算符优先级进行处理,得到23。(ii)在控制台上输入一个表达式,例如,输入1+(3+5)*4,可以按输入的表达式中的括号和运算符串的优先级进行处理,得到33。(iii)设计的计算器可实现实数(含整数)的加、减、乘、除、乘方和开方运算。
(2)拓展功能(20分)(i)设计的计算器可实现复数的加、减、乘、除运算;(ii)设计的计算器可实现无穷精度的整数的加、减、乘、除、求模运算(提示,使用结构体)。
代码如下:
#include <iostream>
#include <stack>
#include <math.h>
using namespace std;
//核心函数,将表达式的每个字符都进行入栈操作
double inStack();
void caluNum(stack<char>& signC, stack<double>& num); //用来计算加减乘除, 结果放在数字栈顶
void factorial(stack<double>& num); //用来计算阶乘
int printprioNum(char priNum); //用来计算操作符的优先级
int main() {
double result; //最后的结果
cout << "请输入表达式:\n";
result = inStack(); //将缓冲区的操作符和数字压入栈
cout << "结果是:\n" << result;
return 0;
}
double inStack() {
//定义一个符号栈--用来存储符号
stack<char> signC;
//定义一个数字栈--用来存储数字
stack<double> num;
char signOne;
double num_;
while (1) {
//cin.peek()返回的是表达式中的每一个字符对应的ASCLL表的值,
//通过ASCLL表的值可以对数字进行筛选出来,将数字进行入栈
if (cin.peek() >= '0' && cin.peek() <= '9') { //判断下一个是否是数字
//遇到数字忽略,继续输入
cin >> num_;
//num_打印的是数字
cout << num_ << endl;
//数字直接入数字栈
num.push(num_);
}
else {
//如果不是数字,那输入的一定是运算符
cin >> signOne;
if (signOne == '=') {
//如果符号栈不空,表明计算还未完成,就一直要计算
while (!signC.empty()) caluNum(signC, num);
//如果是等号且符号栈顶为空,表明已经计算出最终的结果了,就返回数字栈顶元素--也就是最终的结果
return num.top();
}
//如果是!就阶乘
else if (signOne == '!') factorial(num);
//如果符号是左括号或符号栈为空直接压入符号栈,因为括号优先级最大,应该要把括号里面的值
else if (signOne == '(' || signC.empty()) signC.push(signOne);
//如果是右括号,则while循环判断符号栈顶元素是否为左括号,如果是左括号就表示()完整的截取到了
//这时候我们要计算完整括号里面的值,因为括号优先级是最大的。
else if (signOne == ')') {
while (signC.top() != '(') caluNum(signC, num);
//计算完成后左括号出栈
signC.pop();
}
//针对于括号除外的其他运算符的优先级,我们采用符号返回的数字大小来决定优先级的大小
//如果栈顶符号的优先级大于等于当前符号优先级的话,进入while循环
else if (printprioNum(signC.top()) >= printprioNum(signOne)) {
while (signC.top() != '(') {
//计算结果压入数字栈,取出当前栈顶
caluNum(signC, num);
//当符号栈为空或者待压入的符号优先级比符号栈顶元素高就跳出
if (signC.empty() || printprioNum(signC.top()) < printprioNum(signOne)) {
cout <<"当符号栈为空或者待压入的符号优先级高就跳出" << endl;
break;
}
}
//压入当前符号
signC.push(signOne);
}
else {
//否则就压入符号栈
signC.push(signOne);
}
}
}
}
void caluNum(stack<char>& signC, stack<double>& num) {
double a, b;
//针对于负数参与运算的处理
if (signC.top() == '-') {
a = num.top();
num.pop();
signC.pop(); //取出负号
if (!num.empty()) {
if (signC.empty() || num.size() == signC.size())
//如果前面还有数字,就压入+,即变成加负值
signC.push('+');
}
num.push(-a); //压入负值
}
else {
a = num.top();
num.pop();
b = num.top();
num.pop();
cout << "a:"<<a << endl;
cout <<"b:" << b << endl;
if (signC.top() == '+') num.push(b + a);
else if (signC.top() == '*') num.push(b * a);
else if (signC.top() == '/') num.push(b / a);
else if (signC.top() == '^') num.push(pow(b, a));
else if (signC.top() == '√') num.push(sqrt(a));
signC.pop();
}
}
void factorial(stack<double>& num) {
int a = static_cast<int>(num.top()); num.pop();
int result = 1;
for (int i = 1; i <= a; i++) result *= i;
num.push(static_cast<double>(result));
}
//放回优先级,优先级高的先运算
int printprioNum(char priNum) {
//根据传入的符号,返回符号的优先级数字,数字高表示符号的优先级也就越高
if (priNum == '(') return 0;
else if (priNum == '+' || priNum == '-') return 1;
else if (priNum == '*' || priNum == '/') return 2;
//乘方的优先级在当前运算中是最高的
else if (priNum == '^') return 3;
}