簡體   English   中英

搜索匹配的括號

[英]Search for matching parenthesis

所以我的背景不是 CS,我把編程當成了一種愛好。 無論如何,我需要解決這個問題:給定一個像“([])”這樣的表達式,檢查這個表達式是否有匹配的括號樣式,即匹配“[”和匹配“(”。

我確實意識到有解決方案,但那些處理堆棧的方法我還沒有了解它。 所以我嘗試了我自己的,看起來很意大利面,但它有效。

/* Program to check if parens are balanced */

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

int main(){

  char expr[100] = "[)";

  int roundcounter = 0, squarecounter = 0, i = 0;

  while (expr[i] != '\0') {
    if (expr[i] == '(') {
      roundcounter++;
    }
    else if (expr[i] == ')') {
      roundcounter--;
      if (roundcounter < 0) {
    break;
      }
    }


    if (expr[i] == '[') {
      squarecounter++;
    }
    else if (expr[i] == ']') {
      squarecounter--;
      if (squarecounter < 0) {
    break;
      }
    }

    i++;
  }

  if (roundcounter == 0 && squarecounter == 0) {
    printf("Balanced parenthesis !\n");
  }

  else {
      printf("Unbalaced !\n");      

      /* Error for [ ] */
      if (squarecounter > 0) {
    printf("Missing right square bracket\n");
      }
      else if (squarecounter < 0) {
    printf("Missing left square bracket\n");
      }

      /* Error for ( ) */
      if (roundcounter > 0) {
    printf("Missing right round bracket\n");
      }
      else if (roundcounter < 0) {
    printf("Missing left round bracket\n");
      }
  }
  return 0;
}

基本上,有兩個計數器,每個計數器負責比較 () 和 [],如果左括號增加 (+1) 或如果右括號減少 (-1)。 如果 counters = 0,那么我們有余額表達式。

有一個更好的方法嗎? 我正在考慮創建一個關閉和打開的字符數組:

char openarr[] = {'[', '('};
char closenarr[] = {']', ')'};

但后來我不確定如何繼續。 我可以循環遍歷 openarr 並說如果 expr[i] 匹配 openarr 然后增加計數器,並對 closearr 執行相同的操作。

但是,由於以下情況,我們仍然需要 1 個以上的計數器。 假設我們有 expr = "[)" 並且只有 1 個計數器,比如 x。

For loop for openarr will pass because: expr[i] has [ element, counter = 1
For loop for closearr will pass because: expr[i] has ) element, counter = 0

expr = "[)" 肯定不是這種情況

請讓我知道如何改進這一點。

它是不可能在這種或那種形式正確地做到這一點無需堆棧。 你這樣做的方式不能正確處理嵌套。 例如,它會錯誤地接受“[(])”

您的解決方案遇到的問題是您需要記住遇到開括號和方括號的順序。 我建議您只使用一個計數器,當您遇到[(並在遇到]或 時減少)並且您有一個數組,該數組記錄您在計數時遇到的哪種類型的括號。

下面的解決方案保留了一個數組,當您減少括號計數時,需要匹配哪種類型的括號。 如果,當您減少括號計數時,它得到錯誤類型的括號,那就是不匹配。

    char expr[100] = "[([)][]]";
    char brackets[100]; // In a real application, allocate dynamically to the same length as the string
    int bracketCount = 0;
    for (int i = 0 ; i < 100 || expr[i] == '\0' ; ++i)
    {
        if (expr[i] == '[' || expr[i] == '(') 
        {
            // Record the type of *closing* bracket we expect when we get back
            // down to this bracket count
            brackets[bracketCount] = expr[i] == '[' ? ']' : ')';
            bracketCount++;
        }
        else if (expr[i] == ']' || expr[i] == ')')
        {
            bracketCount--;
            if (bracketCount < 0 || brackets[bracketCount] != expr[i] )
            {
                printf("Unmatched\n");
                return 1;
            }
        }
    }
    if (bracketCount > 0)
    {
        printf("Unmatched\n");
        return 1;
    }
    printf("matched\n");
    return 0;

你就是這樣:一個沒有堆棧的解決方案1

1好吧,我撒謊了,它確實使用了堆棧。 數組bracketsint brackets bracketCount形成一個堆棧。

正如已回答的那樣,您需要一個堆棧才能匹​​配括號本身。 這個想法是在它們離開時將括號推入 stak(如果你得到一個[你推它,或者如果你遇到一個左邊(你推它)當你找到一個正確的]) ,然后你彈出這個角色堆棧的彈出並查看它是否與您遇到的類型相同......如果它們是相同的類型,那么它們匹配,並且您拋出兩者並繼續下一個。 如果在某些時候您嘗試從堆棧中彈出並且堆棧是空的,或者您到達輸入的末尾並且堆棧仍然有一些內容......那么您的括號不平衡,並且您有錯誤。 讓我們用以下輸入檢查這個算法:

[(])

你的第一個字符是一個 left [ ,所以你推它,給你這個堆棧:

[

當你讀取下一個字符時,因為它是一個左( ,你推它,得到這個堆棧:

[(

當下一個字符出現時, a ] ,你彈出你的最后一個字符,並得到一個( ,它們不匹配......你在那個時候失敗了......實際上這是第一個不匹配的字符。

讓我們嘗試另一個例子:

[()]]

首先,你推送[ ,然后你推送( ,然后你得到)並彈出( ,得到一個匹配的對。此時的堆棧內容是:

[

然后你得到下一個字符,一個]與 statck 的頂部匹配(你彈出一個[ ,讓堆棧為空)當下一個字符到達時 (a ] ) 你彈出堆棧以獲得匹配的[ ,但是你得到了堆棧為空,因此您發出錯誤信號,表明輸入中有未配對的右]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM