一个简易的C++计算器
本帖最后由 jjyz 于 2025-5-5 13:06 编辑作为一个初一的学生,有点兴趣爱好是正常的,这是我用空闲时间搓出来的一个作品(根据其他人的作品改编,增加了步骤以及解一元一次方程):
我就只展示我更改的部分吧
1.计算步骤解析:double getVal(double &s, double e, string str) {
if (str == '(' || str == '[' || str == '{') {
double news, newe, i;
i = 1;
news = s + 1;
while (i) {
s++;
if (s == e)
break;
if (str == '(' || str == '[' || str == '{')
i++;
else if (str == ')' || str == ']' || str == '}')
i--;
}
newe = s - 1;
s++;
double result = cal(news, newe, str);
cout << "计算括号内表达式 " << str.substr(news, newe - news + 1) << " 的值为: " << result << endl;
return result;
}
double val;
if (str == 's') {
s = s + 3;
double arg = getVal(s, e, str);
val = sin(arg);
cout << "计算 sin(" << arg << ") 的值为: " << val << endl;
} else if (str == 'c') {
s = s + 3;
double arg = getVal(s, e, str);
val = cos(arg);
cout << "计算 cos(" << arg << ") 的值为: " << val << endl;
} else if (str == 't') {
s = s + 3;
double arg = getVal(s, e, str);
val = tan(arg);
cout << "计算 tan(" << arg << ") 的值为: " << val << endl;
} else if (str == 'a') {
s++;
if (str == 's') {
s = s + 3;
double arg = getVal(s, e, str);
val = asin(arg);
cout << "计算 asin(" << arg << ") 的值为: " << val << endl;
} else if (str == 'c') {
s = s + 3;
double arg = getVal(s, e, str);
val = acos(arg);
cout << "计算 acos(" << arg << ") 的值为: " << val << endl;
} else if (str == 't') {
s = s + 3;
double arg = getVal(s, e, str);
val = atan(arg);
cout << "计算 atan(" << arg << ") 的值为: " << val << endl;
}
} else if (str >= '0' && str <= '9') {
val = str - '0';
while (s < e && str >= '0' && str <= '9') {
val *= 10;
val += str - '0';
}
if (str == '!') {
int n = static_cast<int>(val);
val = f(n);
cout << "计算 " << n << "! 的值为: " << val << endl;
s++;
}
if (str == '.') {
s = s + 1;
double val2 = str - '0';
while (s < e && str >= '0' && str <= '9') {
val2 *= 10;
val2 += str - '0';
}
while (val2 >= 1) {
val2 /= 10;
}
val = val + val2;
cout << "处理小数部分,得到值为: " << val << endl;
}
}
return val;
}
2:解一元一次方程:// 解析方程,将方程分为左右两部分
void parseEquation(const string& equation, string& left, string& right) {
size_t equalPos = equation.find('=');
if (equalPos != string::npos) {
left = equation.substr(0, equalPos);
right = equation.substr(equalPos + 1);
}
}
// 合并同类项,计算 x 的系数和常数项
void collectTerms(const string& expr, double& xCoeff, double& constant) {
double currentCoeff = 1;
double currentSign = 1;
double num = 0;
bool hasX = false;
for (size_t i = 0; i < expr.length(); ++i) {
if (isdigit(expr)) {
num = num * 10 + (expr - '0');
} else if (expr == 'x') {
hasX = true;
if (i == 0 || !isdigit(expr)) {
num = 1;
}
} else if (expr == '+' || expr == '-') {
if (hasX) {
xCoeff += currentSign * currentCoeff * num;
} else {
constant += currentSign * num;
}
num = 0;
hasX = false;
currentSign = (expr == '+') ? 1 : -1;
currentCoeff = 1;
}
}
if (hasX) {
xCoeff += currentSign * currentCoeff * num;
} else {
constant += currentSign * num;
}
}
// 解一元一次方程
double solveEquation(const string& equation) {
string left, right;
parseEquation(equation, left, right);
double leftXCoeff = 0, leftConstant = 0;
double rightXCoeff = 0, rightConstant = 0;
collectTerms(left, leftXCoeff, leftConstant);
collectTerms(right, rightXCoeff, rightConstant);
double totalXCoeff = leftXCoeff - rightXCoeff;
double totalConstant = rightConstant - leftConstant;
if (totalXCoeff == 0) {
if (totalConstant == 0) {
cout << "方程有无数解。" << endl;
} else {
cout << "方程无解。" << endl;
}
return 0;
}
return totalConstant / totalXCoeff;
}
这是整体代码:#include <iostream>
#include <string>
#include <cmath>
using namespace std;
// 快速幂函数,用于计算 a 的 b 次幂
long long Poww(long long a, long long b) {
long long ans = 1;
long long base = a;
while (b != 0) {
if (b & 1)
ans *= base;
base *= base;
b >>= 1;
}
return ans;
}
// 阶乘函数,计算 n 的阶乘
long long f(int n) {
if (n == 1)
return 1;
if (n > 1)
return n * f(n - 1);
}
// 计算表达式的值,并输出每一步的计算过程
double cal(double s, double e, string str);
// 获取一个操作数或括号内表达式的值,并输出计算过程
double getVal(double &s, double e, string str) {
if (str == '(' || str == '[' || str == '{') {
double news, newe, i;
i = 1;
news = s + 1;
while (i) {
s++;
if (s == e)
break;
if (str == '(' || str == '[' || str == '{')
i++;
else if (str == ')' || str == ']' || str == '}')
i--;
}
newe = s - 1;
s++;
double result = cal(news, newe, str);
cout << "计算括号内表达式 " << str.substr(news, newe - news + 1) << " 的值为: " << result << endl;
return result;
}
double val;
if (str == 's') {
s = s + 3;
double arg = getVal(s, e, str);
val = sin(arg);
cout << "计算 sin(" << arg << ") 的值为: " << val << endl;
} else if (str == 'c') {
s = s + 3;
double arg = getVal(s, e, str);
val = cos(arg);
cout << "计算 cos(" << arg << ") 的值为: " << val << endl;
} else if (str == 't') {
s = s + 3;
double arg = getVal(s, e, str);
val = tan(arg);
cout << "计算 tan(" << arg << ") 的值为: " << val << endl;
} else if (str == 'a') {
s++;
if (str == 's') {
s = s + 3;
double arg = getVal(s, e, str);
val = asin(arg);
cout << "计算 asin(" << arg << ") 的值为: " << val << endl;
} else if (str == 'c') {
s = s + 3;
double arg = getVal(s, e, str);
val = acos(arg);
cout << "计算 acos(" << arg << ") 的值为: " << val << endl;
} else if (str == 't') {
s = s + 3;
double arg = getVal(s, e, str);
val = atan(arg);
cout << "计算 atan(" << arg << ") 的值为: " << val << endl;
}
} else if (str >= '0' && str <= '9') {
val = str - '0';
while (s < e && str >= '0' && str <= '9') {
val *= 10;
val += str - '0';
}
if (str == '!') {
int n = static_cast<int>(val);
val = f(n);
cout << "计算 " << n << "! 的值为: " << val << endl;
s++;
}
if (str == '.') {
s = s + 1;
double val2 = str - '0';
while (s < e && str >= '0' && str <= '9') {
val2 *= 10;
val2 += str - '0';
}
while (val2 >= 1) {
val2 /= 10;
}
val = val + val2;
cout << "处理小数部分,得到值为: " << val << endl;
}
}
return val;
}
// 处理乘、除、幂运算,并输出计算过程
double getVal1(double &s, double e, string str) {
double val;
val = getVal(s, e, str);
while (1) {
if (s < e && str == '*') {
double right = getVal(++s, e, str);
double prev = val;
val *= right;
cout << "计算 " << prev << " * " << right << " 的值为: " << val << endl;
} else if (s < e && str == '/') {
double right = getVal(++s, e, str);
double prev = val;
val /= right;
cout << "计算 " << prev << " / " << right << " 的值为: " << val << endl;
} else if (s < e && str == '^') {
double right = getVal(++s, e, str);
double prev = val;
val = Poww(static_cast<long long>(val), static_cast<long long>(right));
cout << "计算 " << prev << " ^ " << right << " 的值为: " << val << endl;
} else
return val;
}
}
// 处理加、减运算,并输出计算过程
double cal(double s, double e, string str) {
double sum = 0;
if (str != '-')
sum = getVal1(s, e, str);
while (s < e) {
if (str == '+') {
double right = getVal1(++s, e, str);
double prev = sum;
sum += right;
cout << "计算 " << prev << " + " << right << " 的值为: " << sum << endl;
} else if (str == '-') {
double right = getVal1(++s, e, str);
double prev = sum;
sum -= right;
cout << "计算 " << prev << " - " << right << " 的值为: " << sum << endl;
}
}
return sum;
}
// 解析方程,将方程分为左右两部分
void parseEquation(const string& equation, string& left, string& right) {
size_t equalPos = equation.find('=');
if (equalPos != string::npos) {
left = equation.substr(0, equalPos);
right = equation.substr(equalPos + 1);
}
}
// 合并同类项,计算 x 的系数和常数项
void collectTerms(const string& expr, double& xCoeff, double& constant) {
double currentCoeff = 1;
double currentSign = 1;
double num = 0;
bool hasX = false;
for (size_t i = 0; i < expr.length(); ++i) {
if (isdigit(expr)) {
num = num * 10 + (expr - '0');
} else if (expr == 'x') {
hasX = true;
if (i == 0 || !isdigit(expr)) {
num = 1;
}
} else if (expr == '+' || expr == '-') {
if (hasX) {
xCoeff += currentSign * currentCoeff * num;
} else {
constant += currentSign * num;
}
num = 0;
hasX = false;
currentSign = (expr == '+') ? 1 : -1;
currentCoeff = 1;
}
}
if (hasX) {
xCoeff += currentSign * currentCoeff * num;
} else {
constant += currentSign * num;
}
}
// 解一元一次方程
double solveEquation(const string& equation) {
string left, right;
parseEquation(equation, left, right);
double leftXCoeff = 0, leftConstant = 0;
double rightXCoeff = 0, rightConstant = 0;
collectTerms(left, leftXCoeff, leftConstant);
collectTerms(right, rightXCoeff, rightConstant);
double totalXCoeff = leftXCoeff - rightXCoeff;
double totalConstant = rightConstant - leftConstant;
if (totalXCoeff == 0) {
if (totalConstant == 0) {
cout << "方程有无数解。" << endl;
} else {
cout << "方程无解。" << endl;
}
return 0;
}
return totalConstant / totalXCoeff;
}
void jsqbegin() {
string x;
while (cin >> x) {
if (x == "exit") break;
if (x.find('x') != string::npos && x.find('=') != string::npos) {
// 包含未知数 x 且有等号,认为是一元一次方程
cout << "开始解方程: " << x << endl;
double solution = solveEquation(x);
if (solution != 0) {
cout << "方程的解为: x = " << solution << endl;
}
} else {
// 普通表达式,进行计算并输出步骤
cout << "开始计算表达式: " << x << endl;
double result = cal(0, x.length(), x);
cout << "最终计算结果为: " << result << endl;
}
}
}
int main() {
jsqbegin();
return 0;
}
ok,快来运行试试 代码问题分析
我看到你尝试实现括号解析功能,但代码有几个需要修正的地方:
[*]字符串比较错误:应使用 str 访问字符串中的字符,而不是直接比较整个字符串
[*]符号判断错误:'{' 被错误地写成 ' == '{'
[*]括号匹配问题:缺少对三种括号类型的完整判断
修正建议
这是修改后的代码示例:
#include <iostream>
using namespace std;
double getVal(int &s, int e, string str) { // 注意参数类型改为int
if (str == '(' || str == '{') {
double result;
int news = s + 1;
int i = 1; // 用于括号层数计数
while (i > 0 && s < e) {
s++; // 移动指针
if (str == '(' || str == '{') i++;
if (str == ')' || str == '}') i--;
}
int newe = s - 1;
s++; // 跳过当前括号
result = cal(news, newe, str);
cout << "步骤:" << str.substr(news-1, newe-news+2) << " = " << result << endl;
return result;
}
// 其他处理...
}
改进说明
[*]使用 str 来访问字符串中的具体字符
[*]增加 s < e 的边界条件判断,防止越界
[*]简化括号匹配逻辑,使用计数器跟踪括号层数
[*]添加计算步骤的输出提示
测试建议
可以尝试输入这些表达式测试:
[*] (2+3)*4
[*] {5*(3-1)}/2
[*] 2*(1+{3+4})
如果还有疑问,欢迎继续提问!记得在测试时先去掉方程求解部分的代码,先确保基础运算功能正常。
以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页:
[1]