C平衡括号检查器

时间:2015-09-20 19:53:01

标签: c stack

我在使用余额括号检查器工作时遇到了一些麻烦。我的错误在以下代码中

//while the input is not EOF, take in values.
while (input[i] != '\0') {
  //IF input  is an opener, push onto stack
  if (input[i] == '{' ||
      input[i] == '[' ||
      input[i] == '(' ||
      input[i] == '<') {
    push(&st2, input[i]);
  } else if (input[i] == '}' ||
             input[i] == ']' ||
             input[i] == ')' ||
             input[i] == '>') {
    if (isEmpty(st2)) {
      balance = 0;
      break;
    }
  }
  //if input is a closer 

  if (!((input[i] == '}' && top(st2) == '{') ||
        (input[i] == ']' && top(st2) == '[') ||
        (input[i] == ')' && top(st2) == '(') ||
        (input[i] == '>' && top(st2) == '<'))) {
    balance = 0;
    break;
  }

  i++;
  errorpos = i;
  if (input[i] =='\0') {
    if (!isEmpty(st2)) {
      balance = FALSE;
    }
  }
}

我的堆栈实现和获取用户值工作正常,但条件不会。例如,如果我输入{作为输入,则{被推到堆栈顶部,但是它不会在while循环之后检查堆栈是否为空。我已经尝试在isEmpty循环之外移动while评估以查看是否存在问题,但它的行为相同。基本上,无论我输入什么,表达都被认为是平衡的,所以在我看来我的条件是错误的,但是我不知道该怎么做。

2 个答案:

答案 0 :(得分:0)

当遇到结束括号时,你需要做一个pop(),你可能需要进行一些重构才能做到。否则,您的代码看起来应该对我有用。

我确定有一种更简洁的方法可以做到这一点,但为了修复这个确切的代码,我在输入[i]是一个结束括号时和确定之后添加一个if检查没有错误。 if检查将检查结束括号并从堆栈中删除先前匹配的开始括号。

  if (!((input[i]=='}' && top(st2) == '{') ||
        (input[i]==']' && top(st2) == '[') ||
        (input[i]==')' && top(st2) == '(') ||
        (input[i]=='>' && top(st2) == '<'))){
    balance = 0;
    break;
  }
  if (input[i]=='}' || input[i]==']' || input[i]==')' || input[i]=='>') { // New if check
    pop(st2);
  }

答案 1 :(得分:0)

存在多个问题:

  • 遇到近距离时你不会弹出堆栈。
  • 如上所述,pushisEmpty()的实现必须是错误的,因为如果看到任何开启者,堆栈永远不会为空。

以下是改进版本:

#include <stdlib.h>

typedef struct stack {
    int value;
    struct stack *prev;
} stack;

int isEmpty(stack *st) {
    return st == NULL;
}

stack *push(stack **stp, int value) {
    stack *st = malloc(sizeof(*st));
    if (st != NULL) {
        st->value = value;
        st->prev = *stp;
        *stp = st;
    }
    return st;
}

int pop(stack **stp) {
    int value = -1;
    stack *st = *stp;
    if (st != NULL) {
        value = st->value;
        *stp = st->prev;
        free(st);
    }
    return value;
}

int check_balanced(const char *input, int *errorpos) {
    int balance = 1;
    stack *st2 = NULL;

    for (size_t i = 0; balance && input[i] != '\0'; i++) {
        switch (input[i]) {
          // if input is an opener, push the closer onto stack
          case '{': push(&st2, '}'); break;
          case '[': push(&st2, ']'); break;
          case '(': push(&st2, ')'); break;
          case '<': push(&st2, '>'); break;
          // if input is a closer, check the stack
          case '}':
          case ']':
          case ')':
          case '>': if (isEmpty(st2) || pop(&st2) != input[i]) {
                        *errorpos = i;
                        balance = 0;
                    }
                    break;
        }
    }
    if (!isEmpty(st2)) {
        if (balance) {
            *errorpos = i;
            balance = 0;
        }
        while (!isEmpty(st2)) {
            pop(&st2);
        }
    }
    return balance;
}