鱼C论坛

 找回密码
 立即注册
查看: 110|回复: 1

[作品展示] 一个简易的C++计算器

[复制链接]
发表于 7 天前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 jjyz 于 2025-5-5 13:06 编辑

作为一个初一的学生,有点兴趣爱好是正常的,这是我用空闲时间搓出来的一个作品(根据其他人的作品改编,增加了步骤以及解一元一次方程):
我就只展示我更改的部分吧
1.计算步骤解析:
  1. double getVal(double &s, double e, string str) {
  2.         if (str[s] == '(' || str[s] == '[' || str[s] == '{') {
  3.                 double news, newe, i;
  4.                 i = 1;
  5.                 news = s + 1;
  6.                 while (i) {
  7.                         s++;
  8.                         if (s == e)
  9.                                 break;
  10.                         if (str[s] == '(' || str[s] == '[' || str[s] == '{')
  11.                                 i++;
  12.                         else if (str[s] == ')' || str[s] == ']' || str[s] == '}')
  13.                                 i--;
  14.                 }
  15.                 newe = s - 1;
  16.                 s++;
  17.                 double result = cal(news, newe, str);
  18.                 cout << "计算括号内表达式 " << str.substr(news, newe - news + 1) << " 的值为: " << result << endl;
  19.                 return result;
  20.         }
  21.         double val;
  22.         if (str[s] == 's') {
  23.                 s = s + 3;
  24.                 double arg = getVal(s, e, str);
  25.                 val = sin(arg);
  26.                 cout << "计算 sin(" << arg << ") 的值为: " << val << endl;
  27.         } else if (str[s] == 'c') {
  28.                 s = s + 3;
  29.                 double arg = getVal(s, e, str);
  30.                 val = cos(arg);
  31.                 cout << "计算 cos(" << arg << ") 的值为: " << val << endl;
  32.         } else if (str[s] == 't') {
  33.                 s = s + 3;
  34.                 double arg = getVal(s, e, str);
  35.                 val = tan(arg);
  36.                 cout << "计算 tan(" << arg << ") 的值为: " << val << endl;
  37.         } else if (str[s] == 'a') {
  38.                 s++;
  39.                 if (str[s] == 's') {
  40.                         s = s + 3;
  41.                         double arg = getVal(s, e, str);
  42.                         val = asin(arg);
  43.                         cout << "计算 asin(" << arg << ") 的值为: " << val << endl;
  44.                 } else if (str[s] == 'c') {
  45.                         s = s + 3;
  46.                         double arg = getVal(s, e, str);
  47.                         val = acos(arg);
  48.                         cout << "计算 acos(" << arg << ") 的值为: " << val << endl;
  49.                 } else if (str[s] == 't') {
  50.                         s = s + 3;
  51.                         double arg = getVal(s, e, str);
  52.                         val = atan(arg);
  53.                         cout << "计算 atan(" << arg << ") 的值为: " << val << endl;
  54.                 }
  55.         } else if (str[s] >= '0' && str[s] <= '9') {
  56.                 val = str[s++] - '0';
  57.                 while (s < e && str[s] >= '0' && str[s] <= '9') {
  58.                         val *= 10;
  59.                         val += str[s++] - '0';
  60.                 }
  61.                 if (str[s] == '!') {
  62.                         int n = static_cast<int>(val);
  63.                         val = f(n);
  64.                         cout << "计算 " << n << "! 的值为: " << val << endl;
  65.                         s++;
  66.                 }
  67.                 if (str[s] == '.') {
  68.                         s = s + 1;
  69.                         double val2 = str[s++] - '0';
  70.                         while (s < e && str[s] >= '0' && str[s] <= '9') {
  71.                                 val2 *= 10;
  72.                                 val2 += str[s++] - '0';
  73.                         }
  74.                         while (val2 >= 1) {
  75.                                 val2 /= 10;
  76.                         }
  77.                         val = val + val2;
  78.                         cout << "处理小数部分,得到值为: " << val << endl;
  79.                 }
  80.         }
  81.         return val;
  82. }
复制代码

2:解一元一次方程:
  1. // 解析方程,将方程分为左右两部分
  2. void parseEquation(const string& equation, string& left, string& right) {
  3.         size_t equalPos = equation.find('=');
  4.         if (equalPos != string::npos) {
  5.                 left = equation.substr(0, equalPos);
  6.                 right = equation.substr(equalPos + 1);
  7.         }
  8. }

  9. // 合并同类项,计算 x 的系数和常数项
  10. void collectTerms(const string& expr, double& xCoeff, double& constant) {
  11.         double currentCoeff = 1;
  12.         double currentSign = 1;
  13.         double num = 0;
  14.         bool hasX = false;
  15.         for (size_t i = 0; i < expr.length(); ++i) {
  16.                 if (isdigit(expr[i])) {
  17.                         num = num * 10 + (expr[i] - '0');
  18.                 } else if (expr[i] == 'x') {
  19.                         hasX = true;
  20.                         if (i == 0 || !isdigit(expr[i - 1])) {
  21.                                 num = 1;
  22.                         }
  23.                 } else if (expr[i] == '+' || expr[i] == '-') {
  24.                         if (hasX) {
  25.                                 xCoeff += currentSign * currentCoeff * num;
  26.                         } else {
  27.                                 constant += currentSign * num;
  28.                         }
  29.                         num = 0;
  30.                         hasX = false;
  31.                         currentSign = (expr[i] == '+') ? 1 : -1;
  32.                         currentCoeff = 1;
  33.                 }
  34.         }
  35.         if (hasX) {
  36.                 xCoeff += currentSign * currentCoeff * num;
  37.         } else {
  38.                 constant += currentSign * num;
  39.         }
  40. }

  41. // 解一元一次方程
  42. double solveEquation(const string& equation) {
  43.         string left, right;
  44.         parseEquation(equation, left, right);

  45.         double leftXCoeff = 0, leftConstant = 0;
  46.         double rightXCoeff = 0, rightConstant = 0;

  47.         collectTerms(left, leftXCoeff, leftConstant);
  48.         collectTerms(right, rightXCoeff, rightConstant);

  49.         double totalXCoeff = leftXCoeff - rightXCoeff;
  50.         double totalConstant = rightConstant - leftConstant;

  51.         if (totalXCoeff == 0) {
  52.                 if (totalConstant == 0) {
  53.                         cout << "方程有无数解。" << endl;
  54.                 } else {
  55.                         cout << "方程无解。" << endl;
  56.                 }
  57.                 return 0;
  58.         }

  59.         return totalConstant / totalXCoeff;
  60. }
复制代码

这是整体代码:
  1. #include <iostream>
  2. #include <string>
  3. #include <cmath>
  4. using namespace std;

  5. // 快速幂函数,用于计算 a 的 b 次幂
  6. long long Poww(long long a, long long b) {
  7.         long long ans = 1;
  8.         long long base = a;
  9.         while (b != 0) {
  10.                 if (b & 1)
  11.                         ans *= base;
  12.                 base *= base;
  13.                 b >>= 1;
  14.         }
  15.         return ans;
  16. }

  17. // 阶乘函数,计算 n 的阶乘
  18. long long f(int n) {
  19.         if (n == 1)
  20.                 return 1;
  21.         if (n > 1)
  22.                 return n * f(n - 1);
  23. }

  24. // 计算表达式的值,并输出每一步的计算过程
  25. double cal(double s, double e, string str);

  26. // 获取一个操作数或括号内表达式的值,并输出计算过程
  27. double getVal(double &s, double e, string str) {
  28.         if (str[s] == '(' || str[s] == '[' || str[s] == '{') {
  29.                 double news, newe, i;
  30.                 i = 1;
  31.                 news = s + 1;
  32.                 while (i) {
  33.                         s++;
  34.                         if (s == e)
  35.                                 break;
  36.                         if (str[s] == '(' || str[s] == '[' || str[s] == '{')
  37.                                 i++;
  38.                         else if (str[s] == ')' || str[s] == ']' || str[s] == '}')
  39.                                 i--;
  40.                 }
  41.                 newe = s - 1;
  42.                 s++;
  43.                 double result = cal(news, newe, str);
  44.                 cout << "计算括号内表达式 " << str.substr(news, newe - news + 1) << " 的值为: " << result << endl;
  45.                 return result;
  46.         }
  47.         double val;
  48.         if (str[s] == 's') {
  49.                 s = s + 3;
  50.                 double arg = getVal(s, e, str);
  51.                 val = sin(arg);
  52.                 cout << "计算 sin(" << arg << ") 的值为: " << val << endl;
  53.         } else if (str[s] == 'c') {
  54.                 s = s + 3;
  55.                 double arg = getVal(s, e, str);
  56.                 val = cos(arg);
  57.                 cout << "计算 cos(" << arg << ") 的值为: " << val << endl;
  58.         } else if (str[s] == 't') {
  59.                 s = s + 3;
  60.                 double arg = getVal(s, e, str);
  61.                 val = tan(arg);
  62.                 cout << "计算 tan(" << arg << ") 的值为: " << val << endl;
  63.         } else if (str[s] == 'a') {
  64.                 s++;
  65.                 if (str[s] == 's') {
  66.                         s = s + 3;
  67.                         double arg = getVal(s, e, str);
  68.                         val = asin(arg);
  69.                         cout << "计算 asin(" << arg << ") 的值为: " << val << endl;
  70.                 } else if (str[s] == 'c') {
  71.                         s = s + 3;
  72.                         double arg = getVal(s, e, str);
  73.                         val = acos(arg);
  74.                         cout << "计算 acos(" << arg << ") 的值为: " << val << endl;
  75.                 } else if (str[s] == 't') {
  76.                         s = s + 3;
  77.                         double arg = getVal(s, e, str);
  78.                         val = atan(arg);
  79.                         cout << "计算 atan(" << arg << ") 的值为: " << val << endl;
  80.                 }
  81.         } else if (str[s] >= '0' && str[s] <= '9') {
  82.                 val = str[s++] - '0';
  83.                 while (s < e && str[s] >= '0' && str[s] <= '9') {
  84.                         val *= 10;
  85.                         val += str[s++] - '0';
  86.                 }
  87.                 if (str[s] == '!') {
  88.                         int n = static_cast<int>(val);
  89.                         val = f(n);
  90.                         cout << "计算 " << n << "! 的值为: " << val << endl;
  91.                         s++;
  92.                 }
  93.                 if (str[s] == '.') {
  94.                         s = s + 1;
  95.                         double val2 = str[s++] - '0';
  96.                         while (s < e && str[s] >= '0' && str[s] <= '9') {
  97.                                 val2 *= 10;
  98.                                 val2 += str[s++] - '0';
  99.                         }
  100.                         while (val2 >= 1) {
  101.                                 val2 /= 10;
  102.                         }
  103.                         val = val + val2;
  104.                         cout << "处理小数部分,得到值为: " << val << endl;
  105.                 }
  106.         }
  107.         return val;
  108. }

  109. // 处理乘、除、幂运算,并输出计算过程
  110. double getVal1(double &s, double e, string str) {
  111.         double val;
  112.         val = getVal(s, e, str);
  113.         while (1) {
  114.                 if (s < e && str[s] == '*') {
  115.                         double right = getVal(++s, e, str);
  116.                         double prev = val;
  117.                         val *= right;
  118.                         cout << "计算 " << prev << " * " << right << " 的值为: " << val << endl;
  119.                 } else if (s < e && str[s] == '/') {
  120.                         double right = getVal(++s, e, str);
  121.                         double prev = val;
  122.                         val /= right;
  123.                         cout << "计算 " << prev << " / " << right << " 的值为: " << val << endl;
  124.                 } else if (s < e && str[s] == '^') {
  125.                         double right = getVal(++s, e, str);
  126.                         double prev = val;
  127.                         val = Poww(static_cast<long long>(val), static_cast<long long>(right));
  128.                         cout << "计算 " << prev << " ^ " << right << " 的值为: " << val << endl;
  129.                 } else
  130.                         return val;
  131.         }
  132. }

  133. // 处理加、减运算,并输出计算过程
  134. double cal(double s, double e, string str) {
  135.         double sum = 0;
  136.         if (str[s] != '-')
  137.                 sum = getVal1(s, e, str);
  138.         while (s < e) {
  139.                 if (str[s] == '+') {
  140.                         double right = getVal1(++s, e, str);
  141.                         double prev = sum;
  142.                         sum += right;
  143.                         cout << "计算 " << prev << " + " << right << " 的值为: " << sum << endl;
  144.                 } else if (str[s] == '-') {
  145.                         double right = getVal1(++s, e, str);
  146.                         double prev = sum;
  147.                         sum -= right;
  148.                         cout << "计算 " << prev << " - " << right << " 的值为: " << sum << endl;
  149.                 }
  150.         }
  151.         return sum;
  152. }

  153. // 解析方程,将方程分为左右两部分
  154. void parseEquation(const string& equation, string& left, string& right) {
  155.         size_t equalPos = equation.find('=');
  156.         if (equalPos != string::npos) {
  157.                 left = equation.substr(0, equalPos);
  158.                 right = equation.substr(equalPos + 1);
  159.         }
  160. }

  161. // 合并同类项,计算 x 的系数和常数项
  162. void collectTerms(const string& expr, double& xCoeff, double& constant) {
  163.         double currentCoeff = 1;
  164.         double currentSign = 1;
  165.         double num = 0;
  166.         bool hasX = false;
  167.         for (size_t i = 0; i < expr.length(); ++i) {
  168.                 if (isdigit(expr[i])) {
  169.                         num = num * 10 + (expr[i] - '0');
  170.                 } else if (expr[i] == 'x') {
  171.                         hasX = true;
  172.                         if (i == 0 || !isdigit(expr[i - 1])) {
  173.                                 num = 1;
  174.                         }
  175.                 } else if (expr[i] == '+' || expr[i] == '-') {
  176.                         if (hasX) {
  177.                                 xCoeff += currentSign * currentCoeff * num;
  178.                         } else {
  179.                                 constant += currentSign * num;
  180.                         }
  181.                         num = 0;
  182.                         hasX = false;
  183.                         currentSign = (expr[i] == '+') ? 1 : -1;
  184.                         currentCoeff = 1;
  185.                 }
  186.         }
  187.         if (hasX) {
  188.                 xCoeff += currentSign * currentCoeff * num;
  189.         } else {
  190.                 constant += currentSign * num;
  191.         }
  192. }

  193. // 解一元一次方程
  194. double solveEquation(const string& equation) {
  195.         string left, right;
  196.         parseEquation(equation, left, right);

  197.         double leftXCoeff = 0, leftConstant = 0;
  198.         double rightXCoeff = 0, rightConstant = 0;

  199.         collectTerms(left, leftXCoeff, leftConstant);
  200.         collectTerms(right, rightXCoeff, rightConstant);

  201.         double totalXCoeff = leftXCoeff - rightXCoeff;
  202.         double totalConstant = rightConstant - leftConstant;

  203.         if (totalXCoeff == 0) {
  204.                 if (totalConstant == 0) {
  205.                         cout << "方程有无数解。" << endl;
  206.                 } else {
  207.                         cout << "方程无解。" << endl;
  208.                 }
  209.                 return 0;
  210.         }

  211.         return totalConstant / totalXCoeff;
  212. }
  213. void jsqbegin() {
  214.         string x;
  215.         while (cin >> x) {
  216.                 if (x == "exit") break;
  217.                 if (x.find('x') != string::npos && x.find('=') != string::npos) {
  218.                         // 包含未知数 x 且有等号,认为是一元一次方程
  219.                         cout << "开始解方程: " << x << endl;
  220.                         double solution = solveEquation(x);
  221.                         if (solution != 0) {
  222.                                 cout << "方程的解为: x = " << solution << endl;
  223.                         }
  224.                 } else {
  225.                         // 普通表达式,进行计算并输出步骤
  226.                         cout << "开始计算表达式: " << x << endl;
  227.                         double result = cal(0, x.length(), x);
  228.                         cout << "最终计算结果为: " << result << endl;
  229.                 }
  230.         }
  231. }
  232. int main() {
  233.         jsqbegin();
  234.         return 0;
  235. }
复制代码

ok,快来运行试试
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 7 天前 | 显示全部楼层
代码问题分析
我看到你尝试实现括号解析功能,但代码有几个需要修正的地方:

  • 字符串比较错误:应使用 str[s] 访问字符串中的字符,而不是直接比较整个字符串
  • 符号判断错误'{' 被错误地写成 ' == '{'
  • 括号匹配问题:缺少对三种括号类型的完整判断


修正建议
这是修改后的代码示例:

  1. #include <iostream>
  2. using namespace std;

  3. double getVal(int &s, int e, string str) { // 注意参数类型改为int
  4.     if (str[s] == '(' || str[s] == '{') {
  5.         double result;
  6.         int news = s + 1;
  7.         int i = 1; // 用于括号层数计数
  8.         
  9.         while (i > 0 && s < e) {
  10.             s++; // 移动指针
  11.             if (str[s] == '(' || str[s] == '{') i++;
  12.             if (str[s] == ')' || str[s] == '}') i--;
  13.         }
  14.         
  15.         int newe = s - 1;
  16.         s++; // 跳过当前括号
  17.         result = cal(news, newe, str);
  18.         cout << "步骤:" << str.substr(news-1, newe-news+2) << " = " << result << endl;
  19.         return result;
  20.     }
  21.     // 其他处理...
  22. }
复制代码


改进说明
  • 使用 str[s] 来访问字符串中的具体字符
  • 增加 s < e 的边界条件判断,防止越界
  • 简化括号匹配逻辑,使用计数器跟踪括号层数
  • 添加计算步骤的输出提示


测试建议
可以尝试输入这些表达式测试:
  • (2+3)*4
  • {5*(3-1)}/2
  • 2*(1+{3+4})


如果还有疑问,欢迎继续提问!记得在测试时先去掉方程求解部分的代码,先确保基础运算功能正常。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-5-12 16:01

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表