0%

计算器

learned

  • QChar包含了所有的字符()>char), 而switch语句期望获得一个数字,可以用QChar::unicode()进行转换
  • 函数多使用驼峰式命名,与cpp内置函数有所不同
  • 整数处理方式
1
std::abs(result - std::round(result)) < 1e-10
  • 槽的使用

主要代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#include "calculator.h"
#include <QStack>
#include <QString>
#include <QChar>
#include <cmath>

// 辅助函数:获取运算符优先级
int getPriority(QChar op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
return 0;
}

// 辅助函数:执行运算
double applyOperation(double a, double b, QChar op) {
switch (op.unicode()) {
case '+': return a + b;
case '-': return a - b;
case '*': return a * b;
case '/':
if (b == 0) throw "Division by zero";
return a / b;
default: return 0;
}
}

QString calculate(QString expression)
{
try {
// 移除所有空格
expression = expression.replace(" ", "");

QStack<double> values;
QStack<QChar> operators;

for (int i = 0; i < expression.length(); i++) {
QChar c = expression[i];

// 如果是数字,读取完整数字
if (c.isDigit() || c == '.') {
QString numStr;
while (i < expression.length() &&
(expression[i].isDigit() || expression[i] == '.')) {
numStr += expression[i];
i++;
}
i--; // 回退一个字符

bool ok;
double num = numStr.toDouble(&ok);
if (!ok) throw "Invalid number format";
values.push(num);
}
// 如果是左括号,压入运算符栈
else if (c == '(') {
operators.push(c);
}
// 如果是右括号,计算括号内的表达式
else if (c == ')') {
while (!operators.empty() && operators.top() != '(') {
if (values.size() < 2) throw "Invalid expression";

double b = values.top(); values.pop();
double a = values.top(); values.pop();
QChar op = operators.top(); operators.pop();

values.push(applyOperation(a, b, op));
}

if (operators.empty()) throw "Mismatched parentheses";
operators.pop(); // 弹出左括号
}
// 如果是运算符
else if (c == '+' || c == '-' || c == '*' || c == '/') {
// 处理负号(一元运算符)
if (c == '-' && (i == 0 || expression[i-1] == '(' ||
expression[i-1] == '+' || expression[i-1] == '-' ||
expression[i-1] == '*' || expression[i-1] == '/')) {
// 这是一个负号而不是减号
QString numStr = "-";
i++;
while (i < expression.length() &&
(expression[i].isDigit() || expression[i] == '.')) {
numStr += expression[i];
i++;
}
i--;

bool ok;
double num = numStr.toDouble(&ok);
if (!ok) throw "Invalid number format";
values.push(num);
continue;
}

// 处理普通运算符
while (!operators.empty() &&
getPriority(operators.top()) >= getPriority(c)) {
if (values.size() < 2) throw "Invalid expression";

double b = values.top(); values.pop();
double a = values.top(); values.pop();
QChar op = operators.top(); operators.pop();

values.push(applyOperation(a, b, op));
}
operators.push(c);
}
else {
throw "Invalid character in expression";
}
}

// 处理剩余的运算符
while (!operators.empty()) {
if (values.size() < 2) throw "Invalid expression";

double b = values.top(); values.pop();
double a = values.top(); values.pop();
QChar op = operators.top(); operators.pop();

values.push(applyOperation(a, b, op));
}

// 检查最终结果
if (values.size() != 1 || !operators.empty()) {
throw "Invalid expression";
}

double result = values.top();
// 处理浮点数精度问题,如果结果是整数则显示为整数
if (std::abs(result - std::round(result)) < 1e-10) {
return QString::number(static_cast<long long>(std::round(result)));
} else {
return QString::number(result, 'g', 15); // 保留15位有效数字
}
}
catch (const char* error) {
return QString("Error: ") + error;
}
catch (...) {
return "Error: Unknown error";
}
}