[数据结构题目]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()函数结束

猜你喜欢

转载自www.cnblogs.com/desola/p/12682601.html
今日推荐