C++算法求值函数编译错误及逻辑异常问题求助
算法等式求值函数的问题修复
需求说明
- 若输入的算法等式字符串不含'a':计算等式结果并赋值给
value,函数返回false - 若输入的算法等式字符串包含'a':将
value设为0,函数返回true - 所有逻辑需在
bool Evaluate(const string& expression, int& value)函数内实现
现有代码
#include <string> #include <sstream> #include <cctype> bool Evaluate(const string& expression, int& value){ int a; int b; int c; int d; int e; string valueA; string valueB; string valueC; string valueD; string valueE; int y; int z; unsigned int i; stringstream x; int szz; string alg; if(!expression.find('a')) { szz = expression.size(); alg = expression.copy(0, szz); for (i = 0; i <= szz; ++i) { alg.find_first_of('*/%'); if (isdigit(alg[i] - '*')) { a = alg.find('*'); y = a - 1; z = a + 1; valueA = alg.substr(y, z); a = stoi(valueA); x << a; valueA = x.str(); alg.replace(y, 2, valueA); } if (isdigit(alg[i] - '/')) { b = alg.find('/'); y = b - 1; z = b + 1; valueB = alg.substr(y, z); b = stoi(valueB); x << b; valueB = x.str(); alg.replace(y, 2, valueB); } value = stoi(alg); return false; } else{ value = 0; return true; } }
现存问题
- 布尔返回值逻辑错误:当'a'出现在字符串起始位置时,函数会错误进入计算分支,返回
false而非要求的true - 编译错误:
expression.copy(0, szz)用法错误,string::copy不返回字符串,无法直接赋值给alg - 表达式计算逻辑完全错误:
- 运算符判断条件
isdigit(alg[i] - '*')无意义,无法正确识别乘除运算符 substr参数使用错误,第二个参数应为截取长度而非结束索引- 仅处理单个数字的乘除,无法处理多位数运算
- 未处理运算符优先级,也未支持加减运算
- 字符串流
x未清空,重复使用会导致结果累积错误
- 运算符判断条件
- 循环边界错误:
i <= szz会访问超出字符串长度的索引
修复后的代码实现
#include <string> #include <sstream> #include <cctype> #include <stdexcept> // 辅助函数:从指定位置向左查找连续数字的起始索引 size_t findLeftNumberStart(const std::string& s, size_t pos) { while (pos > 0 && std::isdigit(s[pos - 1])) { --pos; } return pos; } // 辅助函数:从指定位置向右查找连续数字的结束索引 size_t findRightNumberEnd(const std::string& s, size_t pos) { while (pos < s.size() && std::isdigit(s[pos])) { ++pos; } return pos; } // 辅助函数:处理乘除模运算 void handleMulDivMod(std::string& expr) { size_t pos = 0; while ((pos = expr.find_first_of("*/%", pos)) != std::string::npos) { // 找到运算符左右的数字范围 size_t leftStart = findLeftNumberStart(expr, pos); size_t rightEnd = findRightNumberEnd(expr, pos + 1); // 提取左右数字并转换 int left = std::stoi(expr.substr(leftStart, pos - leftStart)); int right = std::stoi(expr.substr(pos + 1, rightEnd - (pos + 1))); int result = 0; // 根据运算符计算 switch (expr[pos]) { case '*': result = left * right; break; case '/': if (right == 0) throw std::invalid_argument("Division by zero"); result = left / right; break; case '%': if (right == 0) throw std::invalid_argument("Modulo by zero"); result = left % right; break; } // 替换表达式中的运算部分为结果 expr.replace(leftStart, rightEnd - leftStart, std::to_string(result)); // 重置pos到替换后的位置,继续查找剩余运算符 pos = leftStart; } } // 辅助函数:处理加减运算 void handleAddSub(std::string& expr) { size_t pos = 1; // 从索引1开始,跳过可能的负号 while ((pos = expr.find_first_of("+-", pos)) != std::string::npos) { // 处理负号开头的情况 if (pos == 0) { ++pos; continue; } size_t leftStart = findLeftNumberStart(expr, pos); size_t rightEnd = findRightNumberEnd(expr, pos + 1); int left = std::stoi(expr.substr(leftStart, pos - leftStart)); int right = std::stoi(expr.substr(pos + 1, rightEnd - (pos + 1))); int result = 0; switch (expr[pos]) { case '+': result = left + right; break; case '-': result = left - right; break; } expr.replace(leftStart, rightEnd - leftStart, std::to_string(result)); pos = leftStart; } } bool Evaluate(const std::string& expression, int& value) { // 先判断是否包含'a' if (expression.find('a') != std::string::npos) { value = 0; return true; } std::string alg = expression; try { // 先处理乘除模(优先级高) handleMulDivMod(alg); // 再处理加减 handleAddSub(alg); // 最终结果赋值 value = std::stoi(alg); } catch (const std::exception& e) { // 处理无效表达式、除零错误等 value = 0; return false; } return false; }
修复说明
- 修正布尔返回值逻辑:直接判断
expression.find('a') != string::npos,包含'a'时返回true,否则进入计算分支 - 修复编译错误:将
alg = expression.copy(0, szz)改为直接赋值alg = expression - 重构表达式计算逻辑:
- 拆分乘除模和加减运算,遵循运算符优先级
- 实现辅助函数查找连续数字的范围,支持多位数运算
- 使用
std::to_string替代字符串流,避免累积错误 - 添加异常处理,应对无效表达式或除零错误
- 修正循环边界:根据动态变化的字符串长度遍历,避免越界访问
内容的提问来源于stack exchange,提问作者silver02
相关产品推荐
相关产品推荐

