16.括號匹配的檢驗(**)
描述:
從鍵盤輸入任意括號序列,編程判斷括號是否匹配。假設允許有三種括號:圓括號()、方括號[]和花括號{},其嵌套的順序隨意。
基本要求及提示:
為了正確檢驗輸入序列的括號匹配問題,要使用棧結構來實現。
(1)在檢驗算法中建立一個棧,讀入圓括號、方括號和大括號組成的序列;
(2)若是左括號直接入棧,等待同類的右括號與之匹配;若讀入的是右括號,不入棧,若與當前棧頂的左括號為同類括號,則二者匹配,將棧頂的左括號出棧,否則屬於不合法的情況;
(3)如果序列已讀盡,而棧中仍有待匹配的左括號,或讀入一個右括號,而棧已空,則均屬不合法情況。
(4)當輸入序列與棧同時變空,則說明所有括號完全匹配。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ERROR 0
#define OK 1
#define FALSE -1
#define TRUE 1
#define MAXSIZE 100
typedef struct node
{
char data[MAXSIZE];
int top;
} SeqStack;
int menu_select();
void InitStack(SeqStack * S);
int Push(SeqStack * S, char x);
int Pop(SeqStack * S, char * x);
int GetTop(SeqStack * S, char * x);
void introduce();
int IsEmpty(SeqStack * S);
int Match(char a, char b);
int menu_select() // 菜單驅動程序
{
int sn;
printf(" 括號匹配\n"); // 顯示菜單
printf("==============================\n");
printf(" 1、題目介紹\n");
printf(" 2、括號匹配\n");
printf(" 0、退出\n");
printf("==============================\n");
printf(" 請選擇0--2: ");
for (;;) // 菜單功能選擇
{
scanf("%d", &sn);
getchar();
if (sn < 0 || sn>2)
{
printf("\n 輸入選擇錯誤,請重新選擇 0--2: ");
while (getchar() != '\n');
}
else
break;
}
return sn;
}
/*
TODO: 括號匹配的檢驗
功能描述:利用堆棧技術來檢驗該字符串中的括號是否匹配
循環逐一掃描該字符串,判斷字符串中的括號是否匹配
若是左括號直接入棧,等待同類的右括號與之匹配;若讀入的是右括號,不入棧,若與當前棧頂的左括號為同類括號,則二者匹配,將棧頂的左括號出棧,
若與當前棧頂的左括號為不同類括號,返回2
如果序列已讀盡,而棧中仍有待匹配的左括號,返回3,讀入一個右括號,而棧已空,返回1
當輸入序列與棧同時變空,則說明所有括號完全匹配,返回0
參數說明: str為輸入的字符串
返回值說明: 括號匹配的結果,0:表示括號匹配,1:表示右括號多余,2:表示對應的括號不同類,3:表示左括號多余
*/
int BracketMatch(char *str)
{
SeqStack* compstack = (SeqStack*)malloc(sizeof(SeqStack));
InitStack(compstack);
int i = 0;
char top;
while(str[i]!=0)///這個程序內部有非常多的邏輯判斷,每個都要想清楚,明確每個if語句的判斷條件后,翻譯題意即可
{
if(str[i]!='(' && str[i]!=')' && str[i]!='[' && str[i]!=']' && str[i]!='{' && str[i]!='}')//如果是其他字符,就略過
{
i++;
continue;
}
if((str[i]==')' || str[i]==']' || str[i]=='}') && IsEmpty(compstack) == 1)//如果掃描到右括號且棧已空,就返回1
{
return 1;
}
else if(str[i]=='(' || str[i]=='[' || str[i]=='{')//如果掃描到左括號,就直接入棧
{
Push(compstack, str[i]);
i++;
continue;
}
else if(str[i]==')' || str[i]==']' || str[i]=='}')//如果掃描到右括號
{
GetTop(compstack, &top);
if((top == '(' && str[i]==')') || (top == '[' && str[i]==']') || (top == '{' && str[i]=='}'))//棧頂元素對比當前元素,是否配對
{
Pop(compstack, &top);//是的話,彈出
i++;
continue;
}
else
{
return 2;//否則返回2,表示不配對
}
}
}
if(IsEmpty(compstack) != 1)//如果棧未空,序列已空,
{
return 3;//返回3,左括號多余
}
else//否則,返回0,完全匹配
{
return 0;
}
}
void InitStack(SeqStack * S)
{
S->top = -1;
}
int Push(SeqStack * S, char x)
{
if (S->top == MAXSIZE - 1)
return FALSE;
S->top++;
S->data[S->top] = x;
return TRUE;
}
int Pop(SeqStack * S,char * x)
{
if (S->top == -1)
return FALSE;
else
{
*x = S->data[S->top];
S->top--;
return TRUE;
}
}
int GetTop(SeqStack * S, char * x)
{
if (S->top == -1)
return FALSE;
else
{
*x = S->data[S->top];
return TRUE;
}
}
void introduce()
{
printf("利用堆棧技術檢驗該字符串是否匹配\n");
}
int IsEmpty(SeqStack * S)
{
if (S->top == -1)
return 1;
else
return 0;
}
int Match(char a, char b)
{
if ((a == '(' && b==')' )||(a=='[') && b==']'||(a=='{' && b=='}'))
return 1;
else
return 0;
}
int main()
{
char str[MAXSIZE];
for (;;) // 無限循環,選擇0 退出
{
switch (menu_select()) // 調用菜單函數,按返回值選擇功能函數
{
case 1:
introduce();
break;
case 2:
printf("請輸入字符串");
fgets(str,MAXSIZE,stdin);
switch(BracketMatch(str))
{
case 0:
printf("括號匹配!\n");
break;
case 1:
printf("\n右括號多余!\n");
break;
case 2:
printf("\n對應的括號不同類!\n");
break;
case 3:
printf("左括號多余!\n");
break;
}
break;
case 0:
printf(" 再見!\n"); //退出系統
return 0;
} // switch語句結束
} // for循環結束
} // main()函數結束