用c++实现一个计算器,支持整数、小数的加减乘除四则运算,允许表达式中出现括号。这里默认输入数据均为格式正常表达式,结果精确到小数点后三位。具体解释详见代码注释。
#include <iostream>
#include <list>
#include <sstream>
#include <iomanip>
using namespace std;
struct Token {
string text;
Token(
string text) : text(text) {}
double doubleValue() {
stringstream ss(text);
double value;
ss >> value;
return value;
}
};
class Parser {
struct Tree {
Token token;
Tree * left;
Tree * right;
Tree(Token token) : token(token) {
left =
0;
right =
0;
}
~Tree() {
if (left !=
0)
delete left;
if (right !=
0)
delete right;
}
};
Tree * expression;
double result;
static double execute(Tree * expression) {
if (expression->left ==
0) {
return expression->token.doubleValue();
}
else {
double left = execute(expression->left);
double right = execute(expression->right);
switch (expression->token.text[
0]) {
case '+':
return left + right;
case '-':
return left - right;
case '*':
return left * right;
case '/':
return left / right;
}
return 0;
}
}
public:
Parser() {
expression =
0;
}
~Parser() {
if (expression !=
0)
delete expression;
}
double execute() {
if (expression !=
0) {
result = execute(expression);
delete expression;
expression =
0;
}
return result;
}
void create(
list<Tree*> &subTreeStack,
list<string> &operatorStack) {
Tree* node =
new Tree(Token(operatorStack.back()));
operatorStack.pop_back();
node->right = subTreeStack.back();
subTreeStack.pop_back();
if (!subTreeStack.empty()) {
node->left = subTreeStack.back();
subTreeStack.pop_back();
}
else {
Tree* temp =
new Tree(Token(
"0"));
node->left = temp;
}
subTreeStack.push_back(node);
}
void parse(
string str) {
list<Tree*> subTreeStack;
list<string> operatorStack;
for (
unsigned i =
0; i < str.length(); i++) {
if (str[i] >=
'0' && str[i] <=
'9') {
string value =
"";
for (
unsigned j = i; j < str.length(); j++) {
if ((str[j] >=
'0' && str[j] <=
'9') || str[j] ==
'.') {
value += str[j];
i = j;
}
else {
break;
}
}
Tree* node =
new Tree(Token(value));
subTreeStack.push_back(node);
}
else if (str[i] ==
'+' || str[i] ==
'-') {
string value =
"";
value += str[i];
if (operatorStack.empty()) {
operatorStack.push_back(value);
}
else {
if (i >=
1 && str[i-
1] ==
'(')
subTreeStack.push_back(
new Tree(Token(
"0")));
while (!operatorStack.empty() &&
(operatorStack.back() ==
"+" || operatorStack.back() ==
"-"
|| operatorStack.back() ==
"*" || operatorStack.back() ==
"/")) {
create(subTreeStack, operatorStack);
}
operatorStack.push_back(value);
}
}
else if (str[i] ==
'*' || str[i] ==
'/') {
string value =
"";
value += str[i];
if (operatorStack.empty()) {
operatorStack.push_back(value);
}
else {
while (!operatorStack.empty() &&
(operatorStack.back() ==
"*" || operatorStack.back() ==
"/")) {
create(subTreeStack, operatorStack);
}
operatorStack.push_back(value);
}
}
else if (str[i] ==
'(') {
string value =
"";
value += str[i];
operatorStack.push_back(value);
}
else if (str[i] ==
')') {
while (operatorStack.back() !=
"(") {
create(subTreeStack, operatorStack);
}
operatorStack.pop_back();
}
}
while (!operatorStack.empty()) {
create(subTreeStack, operatorStack);
}
expression = subTreeStack.back();
}
};
int main(
int argc,
char const *argv[]) {
Parser p = Parser();
string expression;
while (
cin >> expression) {
if (expression.length() >
0) {
p.parse(expression);
cout << fixed << setprecision(
3) << p.execute() << endl;
}
}
return 0;
}
含括号的整数测试数据如下:
含括号的整数测试结果如下:
小数测试数据如下:
小数测试结果如下:
正常显示/计算长度数据如下:
正常显示/计算长度结果如下:
从上面测试结果看出,能正常处理含括号的整数小数的四则运算,不足的是能处理的数据最大长度只有16位。
有待改进……
转载请注明原文地址: https://ju.6miu.com/read-678220.html