2015-09-20 81 views
0

我在使平衡括號檢查器正常工作時遇到了一些麻煩。我的錯誤是在下面的代碼C平衡括號檢查器

//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循環之後它不會檢查堆棧是否爲空。我試圖在while循環之外移動isEmpty評估來查看這是否是問題,但它的行爲相同。基本上,不管我輸入什麼,表達式都被認爲是平衡的,所以在我看來,我的條件是錯誤的,但我無法弄清楚在這裏做什麼。

+7

由於有這麼多的問題初學者:爲什麼不正確格式化你的代碼開始?不保證立即解決您的問題,但它肯定會幫助您和其他人更好地瞭解您的代碼中發生了什麼。 – 5gon12eder

+0

darn;只是在我看到5gon12eder的評論之前重新對代碼進行了格式化...他們如此正確 –

+1

您需要將註釋和註釋代碼納入考慮,其中括號可能不會平衡。你還應該忽略字符串文字和字符值賦值的內容,比如'char c ='[';'。 –

回答

0

當你遇到一個結束括號時,你需要做一個pop(),並且你可能需要進行一些重構來完成它。否則,你的代碼看起來應該適用於我。

我確定有一個更乾淨的方法來做到這一點,但要解決這個確切的代碼,我會添加一個if檢查,當輸入[i]是一個結束括號,並且在確定沒有錯誤。 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); 
    } 
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; 
}