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

两段看似相同的括号检查代码为何表现差异巨大?

括号匹配检查函数的逻辑差异问题

我正在编写一个用于词法分析的括号检查函数,要求判断表达式是否完全被一对匹配的括号包裹(遵循规则<expr> ::= "(" <expr> ")")。比如输入(1+2)时返回true,输入(1+2)*(3+4)时返回false。

目前启用的代码版本运行正常,但注释掉的版本执行异常——通过gdb调试发现,注释版本的for循环每次都会直接返回false,无法正常遍历整个表达式。我原本以为两段代码逻辑一致,想不通为什么表现差异这么大。

代码如下:

bool check_parentheses(int p, int q)
{
  int cnt = 0;
  int i = p;
  for(; i <= q; ++i)
  {
    if(tokens[i].type == '(') { ++cnt; }
    else if(tokens[i].type == ')') { --cnt; }
    if(cnt == 0 && tokens[p].type == '(' && tokens[q].type == ')') {break;}
  }
  if(i == q) return true; else return false;
  return false;
 
  // int i = p;
  // for(; i <= q; ++i)
  // {
  //   if(tokens[i].type == '(') {++cnt;}
  //   else if(tokens[i].type == ')') {--cnt;}
  //   if(cnt == 0 && tokens[p].type == '(' && tokens[q].type == ')' && i == q)
  //     return true;
  //   else
  //     return false;
  // }
  // return false;
}

核心逻辑差异分析

两段代码的本质逻辑完全不同:

  • 启用版本:

    1. 遍历整个表达式,维护括号计数cnt
    2. 当计数回到0且首尾是括号时,跳出循环
    3. 最后判断循环结束时的i是否等于q(即是否是在表达式末尾才让计数回到0),以此确定整个表达式被一对括号完整包裹
  • 注释版本:
    在for循环的第一次迭代就会直接返回结果:
    初始i=p,此时处理完括号计数后,判断条件cnt == 0 && tokens[p].type == '(' && tokens[q].type == ')' && i == q。除非p=q(单个括号,不符合合法表达式),否则i==q不成立,直接进入else分支返回false,循环根本没有机会继续遍历后续字符。

简单说,注释版本的逻辑是「每遍历一个字符就立即返回结果」,而启用版本是「遍历到符合条件的位置后再统一判断返回」,这就是两者表现天差地别的原因。

修正注释版本的思路

如果想让注释版本的逻辑和启用版本一致,需要把return语句移出循环,只在循环结束后判断条件返回,或者仅在满足特定条件时提前返回,否则继续循环:

bool check_parentheses(int p, int q)
{
  int cnt = 0;
  int i = p;
  for(; i <= q; ++i)
  {
    if(tokens[i].type == '(') {++cnt;}
    else if(tokens[i].type == ')') {--cnt;}
    
    // 仅当计数回到0且不是遍历到末尾时,提前返回false
    if(cnt == 0 && i != q) {
      return false;
    }
  }
  // 循环结束后判断计数是否为0,且首尾是括号
  return cnt == 0 && tokens[p].type == '(' && tokens[q].type == ')';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 15:27:25