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

C++实现中缀表达式正确性校验的方法与代码答疑

C++中缀表达式输入合法性完整校验实现

你原有写的校验逻辑存在硬编码偏移、规则覆盖不全的问题,比如强制要求首尾必须为括号就不符合中缀表达式语法,固定按位置偏移判断邻接字符完全无法适配多位数、括号嵌套、一元运算符的场景。完整的校验需要从字符合法、括号匹配、词法切分、语法顺序四个维度逐层判断,用状态机+栈的结构实现,不需要硬编码字符位置。

核心校验规则

  • 字符合法性:表达式仅允许出现数字、+ - * / % ^运算符、左右括号、空格,其余字符均为非法
  • 括号匹配:用栈结构存储遍历到的左括号,遇到右括号时栈空则右括号多余,遍历完成栈非空则左括号多余,同时禁止空括号、括号内直接跟运算符的情况
  • 词法合法性:连续数字拼接为一个多位数操作数,禁止两个数字仅用空格分隔(缺运算符)、禁止出现非数字字符和数字拼接的非法token
  • 语法顺序:用状态位标记当前位置期望接收的token类型,要么期望操作数(可以是数字、左括号、一元正负号),要么期望运算符(可以是二元运算符、右括号),不允许出现连续二元运算符、运算符在表达式首尾、运算符直接邻接括号等顺序错误
  • 运算前置校验:可以提前拦截除零、取模操作数非整数这类运行时错误

完整可运行校验代码

#include <string>
#include <stack>
#include <cctype>

enum ErrorCode {
    SUCCESS = 0,
    INVALID_CHAR = -1,
    PAREN_MISMATCH = -2,
    SYNTAX_ORDER_ERROR = -3,
    INVALID_TOKEN = -4,
    INVALID_OPERATION = -5
};

int32_t check_error(const std::string& str) {
    std::stack<char> paren_stack;
    // 初始状态期望读取操作数
    bool expect_operand = true;
    bool last_is_space = false;
    size_t len = str.length();

    for (size_t i = 0; i < len; ++i) {
        char c = str[i];
        if (isspace(c)) {
            last_is_space = true;
            continue;
        }

        // 非法字符校验
        if (!isdigit(c) && c != '+' && c != '-' && c != '*' && c != '/' 
            && c != '%' && c != '^' && c != '(' && c != ')') {
            return INVALID_CHAR;
        }

        // 数字处理逻辑
        if (isdigit(c)) {
            if (!expect_operand) {
                return SYNTAX_ORDER_ERROR;
            }
            // 检查是否为空格分隔的两个独立数字(缺运算符)
            bool prev_is_digit = false;
            for (int j = i-1; j >=0; --j) {
                if (isspace(str[j])) continue;
                prev_is_digit = isdigit(str[j]);
                break;
            }
            if (last_is_space && prev_is_digit) {
                return INVALID_TOKEN;
            }
            // 跳过整个连续数字段,支持任意长度多位数
            while (i < len && isdigit(str[i])) {
                ++i;
            }
            --i; // 回退到数字段最后一位,避免循环跳过后续字符
            expect_operand = false;
            last_is_space = false;
            continue;
        }

        // 左括号处理逻辑
        if (c == '(') {
            if (!expect_operand) {
                return SYNTAX_ORDER_ERROR;
            }
            paren_stack.push(c);
            expect_operand = true;
            last_is_space = false;
            continue;
        }

        // 右括号处理逻辑
        if (c == ')') {
            if (expect_operand || paren_stack.empty()) {
                return PAREN_MISMATCH;
            }
            paren_stack.pop();
            expect_operand = false;
            last_is_space = false;
            continue;
        }

        // 运算符处理逻辑
        bool is_unary = (c == '+' || c == '-') && expect_operand;
        // 不存在一元的乘除模幂运算
        if (!is_unary && expect_operand) {
            return SYNTAX_ORDER_ERROR;
        }
        if ((c == '*' || c == '/' || c == '%' || c == '^') && is_unary) {
            return SYNTAX_ORDER_ERROR;
        }
        expect_operand = true;
        last_is_space = false;
    }

    // 遍历完成后的最终校验
    if (expect_operand) {
        return SYNTAX_ORDER_ERROR;
    }
    if (!paren_stack.empty()) {
        return PAREN_MISMATCH;
    }

    return SUCCESS;
}

和原有逻辑的差异说明

  • 去掉了首尾必须为括号的错误判断,支持无括号的普通中缀表达式
  • 不再用固定位置偏移判断邻接字符,通过逐字符遍历+状态标记适配任意长度的数字、任意数量的合法空格
  • 新增栈结构实现括号完全匹配校验,支持多层嵌套括号的合法性判断
  • 新增一元正负号识别,支持-3+5、( -2 * 4 )这类带一元运算符的合法表达式
  • 覆盖所有顺序错误场景:连续运算符、操作数缺省、括号邻接非法字符、表达式首尾为运算符等

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 14:27:34