我在使用余额括号检查器工作时遇到了一些麻烦。我的错误在以下代码中
//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
评估以查看是否存在问题,但它的行为相同。基本上,无论我输入什么,表达都被认为是平衡的,所以在我看来我的条件是错误的,但是我不知道该怎么做。
答案 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)
存在多个问题:
push
或isEmpty()
的实现必须是错误的,因为如果看到任何开启者,堆栈永远不会为空。以下是改进版本:
#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;
}