学习编程中的Ben 发表于 2024-8-1 21:53:03

同样也来展示一个c++做的计算器

本帖最后由 学习编程中的Ben 于 2024-8-1 21:54 编辑

看了某位仁兄的计算器得了精华,也发一个秀一秀.
主要原理是通过栈来转化成后缀表达式进行计算,中途用 . 来区分数字和数字.
虽然比起 @zhangchenyvn 的短一些,但为了区分优先级,用了很多很多很多判断......
支持 + - * / ^ 五种运算
当时学栈的副产品,写的不好不要吐槽哈

话不多说,秀代码{:10_279:} :
#include <bits/stdc++.h>
using namespace std;
stack<long long> s;
stack<char> sc;
int sum, ss, a, b, j;
char p, hz;
int main() {
        cin >> p;
        for (int i = 0; i < strlen(p); i++){
                if (p >= '0' && p <= '9'){
                        hz = p;
                        if ((p < '0' || p > '9')) hz = '.';
                }else{
                        if (sc.empty()) sc.push(p);
                        else if (p == ')'){
                                while (sc.top() != '('){
                                        hz = sc.top();
                                        sc.pop();
                                }
                                sc.pop();
                        }else if (((p == '*' || p == '/') && (sc.top() != '*' && sc.top() != '/' && sc.top() != '^')) || p == '(' || (p == '^' && sc.top() != '^')) sc.push(p);
                        else{
                                if (p == '+' || p == '-'){
                                        while (!sc.empty()){
                                                if (sc.top() == '(') break;
                                                hz = sc.top();
                                                sc.pop();
                                        }
                                        sc.push(p);
                                }else if(p == '*' || p == '/'){
                                        while (!sc.empty()){
                                                if (sc.top() == '(' || sc.top() == '+' || sc.top() == '-') break;
                                                hz = sc.top();
                                                sc.pop();
                                        }
                                        sc.push(p);
                                }else{
                                        hz = sc.top();
                                        sc.push(p);
                                        sc.pop();
                                }
                        }
                }
        }
        while (!sc.empty()){
                hz = sc.top();
                sc.pop();
        }
        for (int i = 0; i < j; i++){
                if (hz == '.'){
                        sum = 0;
                        for (int j = ss; j < i; j++) sum = sum * 10 + hz - '0';
                        ss = i + 1;
                        s.push(sum);
                }else if (hz < '0' || hz > '9'){
                        b = s.top();
                        s.pop();
                        a = s.top();
                        s.pop();
                        if (hz == '+') s.push(a + b);
                        if (hz == '-') s.push(a - b);
                        if (hz == '*') s.push(a * b);
                        if (hz == '/') s.push(a / b);
                        if (hz == '^') s.push(pow(a, b));
                        ss++;
                }
        }
        cout << s.top();
        return 0;
}

@liuhongrun2022 @陶远航 @歌者文明清理员 @zhangjinxuan @Twilight6
PS:太久没@了, 都不知道谁还在....

FishC 发表于 2024-8-1 21:53:24

嘿,鱼油的提问让我乐得不行!这段 C++ 代码看起来就像是数学界的多功能瑞士军刀,能处理各种运算符,并且使用栈来管理复杂的后缀表达式。接下来我们就来逐步解读一下,希望能带你带入这个“计算器”的世界,别担心,不会让你昏头转向的~

首先,代码从 `#include` 开始,但似乎忘记了包含具体的库函数(例如 `#include <iostream>` 和 `#include <stack>`),这可能是个小失误。没关系,我们来加上这些吧!

接下来的部分,利用栈(stack)来处理算式中的数字和运算符。栈就像一个喝醉了的程序员,只能“后进先出”,所以我们需要把数字和运算符按顺序压入栈中。

#include <iostream>
#include <stack>
#include <cmath>
#include <cstring>

using namespace std;

int main() {
    stack<int> s;   // 数字栈
    stack<char> sc; // 运算符栈
    string p;       // 输入字符串
    int sum, ss, a, b;
    char hz;

    cin >> p; // 读取输入的算式

    for (size_t i = 0; i < p.length(); i++) { // 遍历输入的每一个字符
      // 这里进行判断
      if (isdigit(p)) { // 判断是不是数字
            hz = '.';
            // 继续向后读取完整的数字(这里可以扩展支持多位数)
            while (i < p.length() && isdigit(p)) {
                hz = hz * 10 + (p - '0'); // 计算完整数字
                i++;
            }
            s.push(hz); // 将完整数字压入栈
            i--; // 由于外部for循环也在递增i,这里减去1以调整
      } else {
            // 处理运算符和括号的逻辑
            if (sc.empty() || p == '(') {
                sc.push(p);
            } else if (p == ')') {
                while (sc.top() != '(') {
                  hz = sc.top();
                  sc.pop();
                  // 处理运算符
                  b = s.top(); s.pop();
                  a = s.top(); s.pop();
                  if (hz == '+') s.push(a + b);
                  else if (hz == '-') s.push(a - b);
                  else if (hz == '*') s.push(a * b);
                  else if (hz == '/') s.push(a / b);
                  else if (hz == '^') s.push(pow(a, b));
                }
                sc.pop(); // 去掉 '('
            } else {
                // 处理运算符优先级
                while (!sc.empty() && precedence(sc.top()) >= precedence(p)) {
                  hz = sc.top();
                  sc.pop();
                  // 同样处理运算
                  b = s.top(); s.pop();
                  a = s.top(); s.pop();
                  if (hz == '+') s.push(a + b);
                  else if (hz == '-') s.push(a - b);
                  else if (hz == '*') s.push(a * b);
                  else if (hz == '/') s.push(a / b);
                  else if (hz == '^') s.push(pow(a, b));
                }
                sc.push(p); // 压入当前运算符
            }
      }
    }

    // 最后如果栈不空,依次处理剩余的运算符
    while (!sc.empty()) {
      hz = sc.top();
      sc.pop();
      b = s.top(); s.pop();
      a = s.top(); s.pop();
      if (hz == '+') s.push(a + b);
      else if (hz == '-') s.push(a - b);
      else if (hz == '*') s.push(a * b);
      else if (hz == '/') s.push(a / b);
      else if (hz == '^') s.push(pow(a, b));
    }

    cout << "结果为: " << s.top() << endl; // 输出最终结果
    return 0;
}

总的来说,你的代码非常有趣并且有用,虽然可能需要一些小改动来提高可读性和性能。记住,任何代码都应该像幽默一样——既能表达清楚,又不能太过复杂、让人抓狂!希望这个解释对你有所帮助,继续加油哦!调试的时候就像是在泡咖啡,慢工出细活,别着急!

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

liuhongrun2022 发表于 2024-8-1 23:39:34

强{:5_106:}但是我只能看懂一部分

歌者文明清理员 发表于 2024-8-2 10:27:23

python计算器,我也来秀一秀{:10_256:}:

print(eval(input())

歌者文明清理员 发表于 2024-8-2 10:28:08

*,70%居然没中?

简柠啦 发表于 2024-8-2 14:49:47

{:10_245:}{:10_245:}

zhangchenyvn 发表于 2024-8-2 18:03:46

本帖最后由 zhangchenyvn 于 2024-8-2 18:04 编辑

虽然我看不懂C++,但是在括号处理方面好像比我的更好诶

学习编程中的Ben 发表于 2024-8-2 18:10:38

zhangchenyvn 发表于 2024-8-2 18:03
虽然我看不懂C++,但是在括号处理方面好像比我的更好诶

就是用栈.但是我优先级部分写的极其糟糕...

尹玄睿 发表于 2024-8-9 14:32:51

{:10_277:}

xiangzichen 发表于 2024-8-10 00:35:24

老了,看着代码发怵.

很cool的阳 发表于 2024-8-15 11:46:01

111

18408238295 发表于 2024-8-16 08:28:00

牛,膜拜大佬

很cool的阳 发表于 2024-8-17 16:50:11

厉害

harryhan123 发表于 2024-8-22 20:28:39

666

zsy0226 发表于 2024-8-22 21:02:18

鱼币栈好久没写了,都快看不懂了

学习编程中的Ben 发表于 2024-8-23 09:38:09

zsy0226 发表于 2024-8-22 21:02
鱼币栈好久没写了,都快看不懂了

有可能是因为我写得也比较乱

森林格格屋 发表于 2024-9-3 16:23:14

谢谢
页: [1]
查看完整版本: 同样也来展示一个c++做的计算器