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

开发括号匹配解析器时,能否用enum优化冗余的if条件判断语句?

括号匹配解析器优化方案

现有需求与问题

开发一款简易括号匹配解析器,核心功能为接收字符串输入,校验小括号、中括号、大括号的开闭逻辑正确性,仅校验括号语法,不需要校验括号内表达式有效性,遍历过程中跳过所有非括号字符。
当前存在的问题是parse函数内的非括号字符判断逻辑冗余丑陋,希望找到更优实现方式,比如使用enum优化逻辑。

现有代码

简化parse函数代码

void parse(char *string) {
  for (int i = 0; i < strlen(string); i++) {
    if (string[0] == ')' || string[0] == ']' || string[0] == '}') {
      printf("ParseError: Statement begins with invalid token '%c'", string[0]);
      return;
    }
    if (string[i] != '(' || string[i] != '[' || string[i] != '{' ||
        string[i] != ')' || string[i] != ']' || string[i] != '}') {
      continue;
    }
  }
}

完整程序代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Node {
  char character;
  struct Node *link;
} * top;

struct Node *getNewNode(char);
void push(char);
void pop(void);
void parse(char *);
void print(void);

int main() {
  top = NULL;
  char string[100];
  char *string_ptr = string;
  printf("Enter an expression to parse: ");
  fgets(string, sizeof(string), stdin);
  parse(string_ptr);
  print();
}

struct Node *getNewNode(char character) {
  struct Node *newNode = (struct Node *)(malloc(sizeof(struct Node)));
  newNode->character = character;
  newNode->link = top;
  return newNode;
}

void push(char character) {
  struct Node *newNode = getNewNode(character);
  top = newNode;
}

void pop(void) {
  struct Node *temp;
  if (top == NULL) {
    printf("Stack is empty!");
    return;
  }
  temp = top;
  top = top->link;
  free(temp);
  temp = NULL;
}

void print(void) {
  struct Node *temp = top;
  while (temp != NULL) {
    printf("%c", temp->character);
    temp = temp->link;
  }
}

void parse(char *string) {
  for (int i = 0; i < strlen(string); i++) {
    if (string[0] == ')' || string[0] == ']' || string[0] == '}') {
      printf("ParseError: Statement begins with invalid token '%c'", string[0]);
      return;
    }
    if (string[i] != '(' || string[i] != '[' || string[i] != '{' ||
        string[i] != ')' || string[i] != ']' || string[i] != '}' ||) {
      continue;
    }
  }
}

现有代码问题梳理

首先修正4个明显问题:

  1. 语法错误:第二个if判断末尾多了一个多余的||,会直接触发编译报错,需要先删除
  2. 逻辑错误:非括号判断的条件使用||连接所有“不等于括号”的判断,这个条件永远为真,会导致所有字符都被跳过,后续括号校验逻辑永远不会触发,需要把||替换为&&
  3. 性能问题:每次循环都调用strlen计算字符串长度,会带来O(n²)的不必要性能损耗,建议提前计算字符串长度
  4. 冗余问题:首字符校验逻辑放在循环内,会重复执行,应该提前到循环外

优化方案

方案1:辅助函数简化判断(轻量场景首选)

如果仅需要括号校验功能,不需要后续扩展其他语法解析,封装一个判断是否为括号的工具函数即可,代码简洁易读:

// 辅助函数:判断字符是否为有效括号
int isBracket(char c) {
    return c == '(' || c == '[' || c == '{' || c == ')' || c == ']' || c == '}';
}

改造后的parse函数:

void parse(char *string) {
    // 首字符判断提前到循环外,不需要每次循环都执行
    if (string[0] == ')' || string[0] == ']' || string[0] == '}') {
        printf("ParseError: Statement begins with invalid token '%c'", string[0]);
        return;
    }
    int len = strlen(string);
    for (int i = 0; i < len; i++) {
        char curr = string[i];
        if (!isBracket(curr)) continue;
        // 后续括号匹配逻辑:左括号入栈,右括号判断栈顶是否匹配
    }
}

方案2:enum+查找表优化(适合后续扩展解析器功能)

如果后续要扩展解析器支持更多符号解析,可以用enum定义Token类型,配合查找表快速判断字符类型,后续新增语法类型时修改成本极低:

typedef enum {
    TOKEN_LEFT_PAREN,
    TOKEN_RIGHT_PAREN,
    TOKEN_LEFT_BRACKET,
    TOKEN_RIGHT_BRACKET,
    TOKEN_LEFT_BRACE,
    TOKEN_RIGHT_BRACE,
    TOKEN_OTHER
} TokenType;

TokenType getTokenType(char c) {
    switch(c) {
        case '(': return TOKEN_LEFT_PAREN;
        case ')': return TOKEN_RIGHT_PAREN;
        case '[': return TOKEN_LEFT_BRACKET;
        case ']': return TOKEN_RIGHT_BRACKET;
        case '{': return TOKEN_LEFT_BRACE;
        case '}': return TOKEN_RIGHT_BRACE;
        default: return TOKEN_OTHER;
    }
}

完整的parse逻辑实现:

void parse(char *string) {
    TokenType firstType = getTokenType(string[0]);
    if (firstType >= TOKEN_RIGHT_PAREN && firstType <= TOKEN_RIGHT_BRACE) {
        printf("ParseError: Statement begins with invalid token '%c'", string[0]);
        return;
    }
    int len = strlen(string);
    for (int i = 0; i < len; i++) {
        TokenType type = getTokenType(string[i]);
        if (type == TOKEN_OTHER) continue;
        // 左括号直接入栈
        if (type < TOKEN_RIGHT_PAREN) {
            push(string[i]);
            continue;
        }
        // 右括号匹配校验
        if (top == NULL) {
            printf("ParseError: Extra closing bracket '%c'", string[i]);
            return;
        }
        char topChar = top->character;
        if ((type == TOKEN_RIGHT_PAREN && topChar != '(') ||
            (type == TOKEN_RIGHT_BRACKET && topChar != '[') ||
            (type == TOKEN_RIGHT_BRACE && topChar != '{')) {
            printf("ParseError: Mismatched bracket '%c'", string[i]);
            return;
        }
        pop();
    }
    // 遍历结束后栈非空说明有未闭合的左括号
    if (top != NULL) {
        printf("ParseError: Unclosed brackets left");
        return;
    }
    printf("Parse success: All brackets are matched correctly");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.11 23:39:01