下载资源后端资源详情
计算器源码.zip
大小:12.97KB
价格:42积分
下载量:0
评分:
5.0
上传者:qq_42593411
更新日期:2025-09-22

C++带语法检查的数学算式计算器

资源文件列表(大概)

文件名
大小
计算器源码/include/
-
计算器源码/include/BaseOperatorPro.h
2KB
计算器源码/include/brackCheck.h
1.71KB
计算器源码/include/calmath.h
4.75KB
计算器源码/include/config.h
96B
计算器源码/include/Operator_Value.h
1.75KB
计算器源码/src/
-
计算器源码/src/BaseOperatorPro.cpp
9.75KB
计算器源码/src/brackCheck.cpp
5.19KB
计算器源码/src/main.cpp
4.03KB
计算器源码/src/Operator_Value.cpp
3.34KB

资源内容介绍

适合初学C++的同学看一看,具体可参见博客https://blog.csdn.net/qq_42593411/article/details/136180857?spm=1001.2014.3001.5502
#include"BaseOperatorPro.h"#include"brackCheck.h"//去除字符串末端多余的空格符和制表符并对括号合法性进行判断bool Readformulaline(std::string& line){if (!line.empty()){//去除末尾多余的空格或制表符int _index = line.size() - 1;while (_index >= 0 && (line[_index] == ' ' || line[_index] == '\t'))--_index;line.erase(line.begin() + (_index + 1), line.end());//对括号合法性进行判断return brace_brack_paren_legitmate(line);}elsereturn false;return true;}//根据s返回相应的计算方式标记int mathfunc(std::string s){if (s.compare("sin") == 0)return SIN;else if (s.compare("cos") == 0)return COS;else if (s.compare("exp") == 0)return EXP;else if (s.compare("tan") == 0)return TAN;else if (s.compare("pow") == 0)return POW;else if (s.compare("sqrt") == 0)return SQRT;else if (s.compare("arcsin") == 0)return ARCSIN;else if (s.compare("arccos") == 0)return ARCCOS;else if (s.compare("arctan") == 0)return ARCTAN;else if (s.compare("ln") == 0)return LN;else if (s.compare("lg") == 0)return LG;else if (s.compare("abs") == 0)return ABS;elsereturn NOTFUNC;}/** @brief 对运算符容器进行位置检查,如果出现位置相邻的运算符则报错@param loperators: 解析计算式获得的std::vector<operatorMap>&.@note 只对双元运算符进行位置限制*/bool check_Oper_position(std::vector<operatorMap>& loperators){//如果运算符容器中出现连续位置的运算符,返回错误for (int i = 1; i < loperators.size(); ++i){if (loperators[i].PriorityLevel != 3 && loperators[i - 1].PriorityLevel != 3)//只对双元运算符进行位置限制{if (loperators[i].pos_InString - loperators[i - 1].pos_InString <= 1)return false;}}return true;}/** @brief 传入将计算式解析后的数值容器和运算符容器,根据运算规则计算出结果,如果正确则返回true,错误返回false@param lvalues: 解析计算式获得的std::vector<ValueMap>&.@param loperators: 解析计算式获得的std::vector<operatorMap>&.@param result: inputOutput the calculate result.@note 主要的报错类型有两种: 1.如果运算符找不到相应的计算数值,计算失败返回错误. 2.运算符遍历完毕,数值容器中只能有一个未处理数据,如果多余或者少于则计算失败返回错误*/bool calculateBaseline(std::vector<ValueMap>& lvalues, std::vector<operatorMap>& loperators, double& result){//先对传入容器的位置情况进行检查if (check_Oper_position(loperators) == false){std::cerr << "error: two operators found adjacent in position!" << std::endl;result = ERROR;return false;}//根据运算符优先级对loperators进行排序std::sort(loperators.begin(), loperators.end(), cmp_operatorPriority);for (auto operIt = loperators.begin(); operIt != loperators.end(); ++operIt){//priority level = 3 代表只需要向上寻找一个操作数即可if ((*operIt).PriorityLevel == 3){//从当前操作符开始向上找第一个为处理的数字int operPos = (*operIt).pos_InString;auto Upper_valuePos_it = std::find_if(lvalues.begin(), lvalues.end(),[operPos](const ValueMap& vp) { return (vp.pos_InString > operPos && vp.IsProcess == false); });//错误检查:如果未找到或者,数字位置和运算符位置差大于1,则报错if (Upper_valuePos_it == lvalues.end() || (*Upper_valuePos_it).pos_InString - (*operIt).pos_InString > 1){std::cerr << "error: not exist number to cooperate with current operator: " <<(*operIt).getStringFuncName() << std::endl;result = ERROR;return false;}//没有发生错误进行数值运算double temp = (*Upper_valuePos_it).value;(*Upper_valuePos_it).value = (*operIt).singleCalculate(temp);}else {//priority level = 4,2,1 代表只需要向上向下寻找两个操作数//从当前操作数位置向上向下找未处理的数字int operPos = (*operIt).pos_InString;auto Upper_valuePos_it = std::find_if(lvalues.begin(), lvalues.end(),[operPos](const ValueMap& vp) { return (vp.pos_InString > operPos && vp.IsProcess == false); });//找到了上未处理数字,从上未处理寻找下未处理数字auto lower_valuePos_it = Upper_valuePos_it;//错误检查,并开启向下寻找数字的通道: 如果二元运算符却只有一个数字报错if (Upper_valuePos_it == lvalues.end() || Upper_valuePos_it == lvalues.begin()){std::cerr << "error: not exist number to cooperate with current operator: " <<(*operIt).getStringFuncName() << std::endl;result = ERROR;return false;}else{int i = lower_valuePos_it - lvalues.begin();//为了防止迭代器越界,利用一个变量定义循环范围while (i > 0){--lower_valuePos_it;if ((*lower_valuePos_it).IsProcess == false)//向下找到了未处理数break;--i;}//当i == 0时代表向下未找到if (i == 0){std::cerr << "error: not exist number to cooperate with current operator: " <<(*operIt).getStringFuncName() << std::endl;result = ERROR;return false;}}//已经找到了运算符左右未处理数double temp = (*Upper_valuePos_it).value;(*lower_valuePos_it).IsProcess = true;//将左边的数字置为已处理(*Upper_valuePos_it).value = (*operIt).dualCalculate((*lower_valuePos_it).value, temp);}}//遍历整个数组,如果存在2个以上未处理元素则报错,则当_Not_Process_Count = 1时,程序正确int _Not_Process_Count = 0;for (auto vit = lvalues.begin(); vit != lvalues.end(); ++vit){if ((*vit).IsProcess == false){_Not_Process_Count++;if (_Not_Process_Count < 2)result = (*vit).value;}}if (_Not_Process_Count > 1){std::cerr << "error: the valueContainer include too many value!" << std::endl;result = ERROR;return false;}else if (_Not_Process_Count == 0){std::cerr << "error: not include enough operators!" << std::endl;result = ERROR;return false;}return true;}int getop(const std::string& Subline, int& index, char s[], int& pos){int c, i;if (index >= Subline.size())//字符串已经遍历完毕 return EOFreturn EOF;// remove black spacewhile ((s[0] = c = Subline[index++]) == ' ' || c == '\t');s[1] = '\0';i = 0;if (islower(c))//command or NAME{while (islower(s[++i] = c = Subline[index++]));pos++;index--;s[i] = '\0';if (strlen(s) > 1)return NAME;elsereturn c;//unknown name}if (!isdigit(c) && c != '.' && c != '-')//判断排除空格后获取的第一个字符是否是运算符{pos++;return c;}if (c == '-')//处理负数情况{if (isdigit(c = Subline[index++]) || c == '.')s[++i] = c;else{index--;pos++;return '-';}}if (isdigit(c))while (isdigit(s[++i] = c = Subline[index++]));if (c == '.')while (isdigit(s[++i] = c = Subline[index++]));s[i] = '\0';pos++;index--;//必须自减一次,因为超前赋值了return NUMBER;}bool SubStringProcess(std::string& Subline, double& result){//如果子串(括号中内容)是空的,则返回错误if (Readformulaline(Subline) == false || Subline.empty()){std::cerr << "error: the subline is empty!" << std::endl;result = ERROR;return false;}//定义一行数据中的数值、操作符容器 !!!!!std::vector<operatorMap> lineOperators;std::vector<ValueMap> lineValues;//初始化int type;char s[MAXOP];int pos = 0;int index = 0;//计算过程是否出错标志位bool isgood = true;while ((type = getop(Subline, index, s, pos)) != EOF){if (type == '{' || type == '[' || type == '('){if (type == '{'){int index1 = Subline.find('}', (size_t)index);//从subline中index处开始查找第一次出现的下标std::string Subsubstring = Subline.substr(index, (index1 - index));//index自动指向括号下一个字符index = index1 + 1;//将index更新指向反括号下一个位置double value = 0.0;if (SubStringProcess(Subsubstring, value) == true)lineValues

用户评论 (0)

发表评论

captcha