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

C++将char数组转换为二叉树实现后缀表达式求值问题求助

问题根因分析
  • 段错误核心诱因是单字符逐位读取逻辑不兼容多位数:原有代码大概率是逐char遍历数组时把每个数字字符都单独当做独立操作数生成节点入栈,遇到多位数时会把35拆成3和5两个独立节点,导致后续运算符弹出的节点数量不匹配,栈空时还强行pop就会触发段错误。
  • 额外的越界风险:如果char数组没有正确加\0终止符,遍历的时候会访问非法内存,也会触发段错误。
适配多位数的实现方案

第一步:string转char数组的合规处理

严格符合作业要求的转换逻辑,同时保证终止符存在,示例代码:

std::string expr_str;
getline(infile, expr_str);
// 动态分配char数组,长度+1存储终止符
char* expr_arr = new char[expr_str.size() + 1];
strcpy(expr_arr, expr_str.c_str());

不要直接对c_str()返回的const指针做强制非const转换,避免未定义行为。

第二步:多位数识别与入栈逻辑改造

遍历char数组时新增连续数字拼接逻辑,仅改动操作数读取部分,原有运算符处理逻辑、二叉树构建规则不需要调整:

  • 遍历指针每次遇到数字字符时,开启循环读取所有连续的数字字符,拼接成完整的整型值,再生成操作数节点入栈
  • 遇到空格直接跳过,遇到运算符就正常弹出右、左两个节点,生成运算符节点入栈

后缀表达式的二叉树构建规则本身兼容多位数,仅操作数读取环节需要适配

第三步:入栈步骤边界校验

针对段错误高发点加防御逻辑:

  • 每次生成运算符节点前,先判断栈内节点数是否≥2,不足直接抛出非法表达式错误,避免栈空pop
  • 所有节点指针初始化时显式置空,避免野指针访问
核心代码片段示例
// buildExpressionTree方法内的核心遍历逻辑(基于char数组实现)
stack<node*> st;
int i = 0;
while (expr_arr[i] != '\0') {
    // 跳过空格分隔符
    if (isspace(expr_arr[i])) {
        i++;
        continue;
    }
    // 识别多位数操作数
    if (isdigit(expr_arr[i])) {
        int num = 0;
        // 连续读取所有数字字符
        while (isdigit(expr_arr[i])) {
            num = num * 10 + (expr_arr[i] - '0');
            i++;
        }
        // 生成操作数节点入栈
        node* numNode = new node;
        numNode->data = num; // 可根据节点结构体定义调整存储字段
        numNode->left = numNode->right = nullptr;
        st.push(numNode);
    }
    // 处理运算符
    else if (expr_arr[i] == '+' || expr_arr[i] == '-' || expr_arr[i] == '*' || expr_arr[i] == '/') {
        // 边界校验,避免栈空弹出触发段错误
        if (st.size() < 2) {
            throw invalid_argument("非法后缀表达式:运算符缺少对应操作数");
        }
        node* right = st.top(); st.pop();
        node* left = st.top(); st.pop();
        node* opNode = new node;
        opNode->data = expr_arr[i]; // 运算符可直接存ASCII码,求值时判断类型即可
        opNode->left = left;
        opNode->right = right;
        st.push(opNode);
        i++;
    }
    else {
        throw invalid_argument("表达式存在非法字符");
    }
}
// 最终校验:栈内必须仅剩1个根节点
if (st.size() != 1) {
    throw invalid_argument("非法后缀表达式:节点数量不匹配");
}
root = st.top();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 19:36:00