[英]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好吧,我撒謊了,它確實使用了堆棧。 數組brackets
和int
brackets
bracketCount
形成一個堆棧。
正如已回答的那樣,您需要一個堆棧才能匹配括號本身。 這個想法是在它們離開時將括號推入 stak(如果你得到一個[
你推它,或者如果你遇到一個左邊(
你推它)當你找到一個正確的]
或)
,然后你彈出這個角色堆棧的彈出並查看它是否與您遇到的類型相同......如果它們是相同的類型,那么它們匹配,並且您拋出兩者並繼續下一個。 如果在某些時候您嘗試從堆棧中彈出並且堆棧是空的,或者您到達輸入的末尾並且堆棧仍然有一些內容......那么您的括號不平衡,並且您有錯誤。 讓我們用以下輸入檢查這個算法:
[(])
你的第一個字符是一個 left [
,所以你推它,給你這個堆棧:
[
當你讀取下一個字符時,因為它是一個左(
,你推它,得到這個堆棧:
[(
當下一個字符出現時, a ]
,你彈出你的最后一個字符,並得到一個(
,它們不匹配......你在那個時候失敗了......實際上這是第一個不匹配的字符。
讓我們嘗試另一個例子:
[()]]
首先,你推送[
,然后你推送(
,然后你得到)
並彈出(
,得到一個匹配的對。此時的堆棧內容是:
[
然后你得到下一個字符,一個]
與 statck 的頂部匹配(你彈出一個[
,讓堆棧為空)當下一個字符到達時 (a ]
) 你彈出堆棧以獲得匹配的[
,但是你得到了堆棧為空,因此您發出錯誤信號,表明輸入中有未配對的右]
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.