C/C++——支持括号和自定义运算符的表达式计算器

简介

简单的表达式计算器,输入一个字符串给出计算结果,数字支持小数,符号支持括号“()”和自定义双目运算符(单字符),预定义了+,-,*,/,%,^六种运算符。原理就是中缀表达式string→后缀表达式vector→利用stack计算。

效果

1.测试代码
// 文件名:main.cpp
#include <iostream>
#include "Calculator.h"

using namespace std;

double difference_of_square(double a, double b) {
	// 类型为double(double, double)的函数才能用于注册运算符
    return a * a - b * b;
}

int main() {
	// 新建一个计算器对象
    Calculator cal; 
    // 像函数一样调用计算表达式,答案1.16
    cout << cal("1 + (2 - 3 * 4 / 5) ^ 2") << endl; 
    // 数字中若有多个小数点则第二个点及之后的数字会被忽略(0.5.123.4 => 0.5),答案-0.5
    cout << cal("1 / (4 * 0.5.123.4 - 2*(8^2 % 5 - 2))") << endl; 
    // 除以0会产生NaN
    cout << cal("0 * (1 / 0)") << endl;
    // 注册一个平方差运算符’#‘,优先级为3(高于’*‘,’/‘),运算函数为difference_of_square
    cal.login('#', 3, difference_of_square);
    // 答案0
    cout << cal("3 - ((2 + 3) # 4)^0.5") << endl;
    // 注销幂运算符'^'
    cal.logout('^');
    // 此时遇到’^‘运算符将抛出异常
    try {
        cout << cal("2 ^ 2") << endl;
    }
    catch (runtime_error re) {
        cout << re.what() << endl;
    }
}
2.输出

输出

代码

1.头文件
// 文件名:Calculator.h
#pragma once
#include <iostream>
#include <cmath>
#include <string>
#include <vector>
#include <map>
#include <stack>

class Calculator {
public:
    Calculator();
    void login(char oper, int priory, double(*func)(double, double));
    void logout(char oper);
    double operator()(const std::string& expr);
private:
    std::map<char, int> oper_priorities;
    std::map<char, double(*)(double, double)> oper_funcs;
    double Calculate(const std::vector<std::string>& postfix);
    std::vector<std::string> ToPostfix(const std::string& expr);
    static double add(double a, double b);
    static double sub(double a, double b);
    static double mul(double a, double b);
    static double div(double a, double b);
    static double mod(double a, double b);
    static double pow(double a, double b);
};
2.源文件
// 文件名:Calculator.cpp
#include "Calculator.h"
using namespace std;

Calculator::Calculator() {
	oper_priorities['('] = -1;
	oper_priorities[')'] = -1;
	login('+', 1, add);
	login('-', 1, sub);
	login('*', 2, mul);
	login('/', 2, div);
	login('%', 2, mod);
	login('^', 3, pow);
}

void Calculator::login(char oper, int priory, double(*func)(double, double)) {
	if (oper == '(' || oper == ')') return;
	oper_priorities[oper] = priory;
	if (func != nullptr) oper_funcs[oper] = func;
}

void Calculator::logout(char oper) {
	if (oper == '(' || oper == ')') return;
	oper_priorities.erase(oper);
	oper_funcs.erase(oper);
}

double Calculator::operator()(const string& expr) {
    return Calculate(ToPostfix(expr));
}

double Calculator::Calculate(const vector<string>& postfix) {
    stack<double> nums;
    for (const string& s : postfix) {
        auto it(oper_funcs.find(s[0]));
        if (it == oper_funcs.end()) {
            nums.push(stod(s));
        }
        else {
            double b = nums.top();
            nums.pop();
            double a = nums.top();
            nums.pop();
            nums.push(it->second(a, b));
        }
    }
    return nums.top();
}

vector<string> Calculator::ToPostfix(const string& expr) {
    vector<string> postfix;
    stack<char> opers;
    string num;
    for (char c : expr) {
        if (c == ' ') continue;
        if ('0' <= c && c <= '9' || c == '.') {
            num += c;
            continue;
        }
        if (!num.empty()) {
            postfix.push_back(num);
            num.clear();
        }
        if (c == '(') {
            opers.push(c);
            continue;
        }
        if (c == ')') {
            while (!opers.empty() && opers.top() != '(') {
                postfix.push_back(string(1, opers.top()));
                opers.pop();
            }
            if (opers.empty()) throw runtime_error("Bracket mismatch");
            else opers.pop();
            continue;
        }
        auto it(oper_priorities.find(c));
        if (it != oper_priorities.end()) {
            while (!opers.empty() && it->second < oper_priorities[opers.top()]) {
                postfix.push_back(string(1, opers.top()));
                opers.pop();
            }
            opers.push(c);
            continue;
        }
        throw runtime_error(string("Unknow char: ") + c);
    }
    if (!num.empty()) postfix.push_back(num);
    while (!opers.empty() && opers.top() != '(') {
        postfix.push_back(string(1, opers.top()));
        opers.pop();
    }
    if (!opers.empty()) throw runtime_error("Bracket mismatch");
    return postfix;
}

double Calculator::add(double a, double b) { return a + b; }

double Calculator::sub(double a, double b) { return a - b; }

double Calculator::mul(double a, double b) { return a * b; }

double Calculator::div(double a, double b) {
    if (b == 0) return NAN;
    return a / b;
}

double Calculator::mod(double a, double b) {
    if (b == 0) return NAN;
    return static_cast<int>(a) % static_cast<int>(b);
}

double Calculator::pow(double a, double b) { return std::pow(a, b); }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: c关系逻辑表达式计算器是一种能够计算关系逻辑表达式的工具。它可以处理包括等于、不等于、大于、小于、大于等于、小于等于等关系操作符的表达式,并能够自动进行逻辑运算,包括与、或、非等逻辑操作符。使用这种计算器,我们可以快速准确地计算各种关系逻辑表达式,避免了手算来的繁琐计算、容易出错等问题,提高了计算效率与结果的精确度。 此外,c关系逻辑表达式计算器支持多种输入方式,包括手动输入、复制黏贴等,并且可以同时显示输入表达式和计算结果,便于用户随时查看调整输入表达式、核对计算结果。除此之外,它还具备简单易用的操作界面,使得用户无需复杂的学习与使用过程,即可快速上手使用。这些特点使c关系逻辑表达式计算器成为一个非常有用的计算工具,在日常、工作和学习中发挥着重要的作用。 ### 回答2: 关系逻辑表达式计算器是一种能够解析、计算关系逻辑表达式的工具。该计算器通过输入关系逻辑表达式,自动解析表达式中的逻辑关系,并最终给出表达式的真值。 关系逻辑表达式在数学、计算机科学和形式逻辑等领域中得到了广泛的应用。在这些领域中,关系逻辑表达式常用于表达两个或多个变量之间的关系,以及对这种关系进行条件判断和逻辑推理。例如,在计算机科学中,关系逻辑表达式常用于编写程序中的条件语句和循环语句;在数学中,关系逻辑表达式则常用于数学证明中的推理步骤。 而关系逻辑表达式计算器,则为用户提供了一个便捷的工具,可以帮助用户快速解析和计算其所需的关系逻辑表达式。在使用该计算器时,用户只需输入表达式,输入表达式中所用的逻辑运算符和变量,并点击计算器的计算按钮即可。 除此之外,一些高级的关系逻辑表达式计算器还可以提供额外的功能,例如:支持嵌套表达式支持多种逻辑运算符支持多种参照值等。这些功能可以帮助用户更清晰地编写复杂的关系逻辑表达式,并能得到更准确的计算结果。 总之,关系逻辑表达式计算器是一种非常实用的工具,能够帮助用户更快、更准确地计算和解析复杂的关系逻辑表达式,是数学、计算机科学和形式逻辑等领域的重要工具之一。 ### 回答3: c是一款关系逻辑表达式计算器,它可以通过输入关系逻辑表达式,运算出结果。在计算器的界面上,用户可以输入变量、运算符括号,通过操作符的逻辑运算,计算出最终的逻辑结果。c计算器支持常用的逻辑操作符,如“与”(AND)、“或”(OR)、“非”(NOT)等,同时也支持其他进阶的逻辑运算符,如“异或”(XOR)等。 c计算器主要应用于计算机科学、数学等领域,它可以帮助我们在逻辑判断和决策过程中,快速准确地得出结果。例如,为了判断一个事物是否满足一定的条件,我们可以将条件表达式输入进c计算器中进行运算,得到最终的逻辑结果。此外,c计算器还可以帮助我们进行逻辑运算的拓展,比如布尔代数中的逻辑和与逻辑或等等。 总的来说,c计算器是一款实用、高效的逻辑计算工具,它帮助我们在实际工作和生活中更加方便地进行逻辑运算。这款计算器在线上和离线上都有应用,且使用起来简单易懂,越来越受到广大用户的欢迎。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值