[數據結構題目]16.括號匹配的檢驗(**)


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()函數結束


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM