You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;
    }
}

现存问题

  1. 布尔返回值逻辑错误:当'a'出现在字符串起始位置时,函数会错误进入计算分支,返回false而非要求的true
  2. 编译错误:expression.copy(0, szz)用法错误,string::copy不返回字符串,无法直接赋值给alg
  3. 表达式计算逻辑完全错误:
    • 运算符判断条件isdigit(alg[i] - '*')无意义,无法正确识别乘除运算符
    • substr参数使用错误,第二个参数应为截取长度而非结束索引
    • 仅处理单个数字的乘除,无法处理多位数运算
    • 未处理运算符优先级,也未支持加减运算
    • 字符串流x未清空,重复使用会导致结果累积错误
  4. 循环边界错误: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;
}

修复说明

  1. 修正布尔返回值逻辑:直接判断expression.find('a') != string::npos,包含'a'时返回true,否则进入计算分支
  2. 修复编译错误:将alg = expression.copy(0, szz)改为直接赋值alg = expression
  3. 重构表达式计算逻辑:
    • 拆分乘除模和加减运算,遵循运算符优先级
    • 实现辅助函数查找连续数字的范围,支持多位数运算
    • 使用std::to_string替代字符串流,避免累积错误
    • 添加异常处理,应对无效表达式或除零错误
  4. 修正循环边界:根据动态变化的字符串长度遍历,避免越界访问

内容的提问来源于stack exchange,提问作者silver02

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:30:44