用栈解决----括号匹配问题(MatchBrackets)

问题:给出一个字符数组,判断里边的括号是否匹配。
分析:首先我们要确定用什么方法来解决这个问题,然后再进一步分析过程。
我们可以用栈来解决这个问题,如果是左括号我们就让它入栈,如果是右括号,我们先要判断它和栈顶元素(左括号)是否匹配,如果匹配,我们就让左括号出栈,依次进行,直到栈空时结束,当然如果在前边如果出现匹配不正确,我们直接返回,不用再向后进行了。
栈的特点:后进先出
这里写图片描述
好了,这个过程我们已经分析完了,我们就来看看代码吧,其实语言并不难,难的只是一个问题的分析过程,只要我们把这个问题分析清楚了,只要用语言把这个过程翻译过来就行。

MatchBrackets.h//头文件

#ifndef __MATCHBRACKETS_H__
#define __MATCHBRACKETS_H__

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

#define MaxSize 20

typedef char SDataType;
typedef struct Stack
{
    int top;
    SDataType _arry[MaxSize];
}Stack;

void MatchBrackets(Stack* ps, int sz);
int IsBrackets(char arry[], int i);
int StackSize(Stack* ps);
void StackPush(Stack* ps, SDataType data, char arry[]);
void StackPop(Stack* ps);
int StackEmpty(Stack* ps);
void StackInit(Stack* ps);

#endif //__MATCHBRACKETS_H__

MatchBrackets.c//源文件

#include"MatchBrackets.h"

int IsBrackets(char arry[], int i)
{
    if (('(' == arry[i]) || (')' == arry[i]) || ('[' == arry[i]) || (']' == arry[i]) || ('{' == arry[i]) || ('}' == arry[i]))
        return 1;//是括号
    else
        return 0;
}

int StackSize(Stack* ps)
{
    assert(ps != NULL);
    return ps->top;
}

void StackPush(Stack* ps, SDataType data)
{
    assert(ps != NULL);
    if (ps->top == MaxSize)
        return;
    else
    {
        ps->_arry[ps->top] = data;
        ps->top++;
    }
}

void StackPop(Stack* ps)
{
    assert(ps != NULL);
    if (ps->top)
        ps->top--;

}

int StackEmpty(Stack* ps)
{
    assert(ps != NULL);
    if (0 == ps->top)
        return 1;
    else
        return 0;
}

void StackInit(Stack* ps)
{
    assert(ps != NULL);
    ps->top = 0;
}

void MatchBrackets(Stack* ps, int sz, char arry[])
{
    int i = 0;
    int k = 0;//因为传的是指针,所以要定义一个形参
    assert(ps != NULL);
    //char ch = 0;
    while (i < sz)
    {
        if (IsBrackets(arry, i))//是括号
        {
            //如果是左括号,入栈
            if (('(' == arry[i]) || ('[' == arry[i]) || ('{' == arry[i]))
            {
                StackPush(ps, arry[i]);
                i++;
                continue;
            }
            else if ((')' == arry[i]) || (']' == arry[i]) || ('}' == arry[i]))
            {
                if (0 == ps->top)  //判断栈是否为空,若为空,则右括号比左括号多
                {
                    printf("右括号比左括号多!\n");
                    return;
                }
                else
                {
                    k = ps->top;
                    char ch = ps->_arry[--k];//error:ch = ps->_arry[--(ps->top)]---因为ps->top已经减1了,传递是指针,所以实参ps->top也-1了(此时ps->top已经指向栈顶了),但在下边要出栈(先-1,再出栈,出的就不是栈顶指针了,就会出错,所以我们要定义一个形参k,对形参的改变不会引起对实参的改变),
                    //如果右括号与左括号匹配,左括号出栈
                    if (((')' == arry[i]) && ('(' == ch)) ||
                        ((']' == arry[i]) && ('[' == ch)) ||
                        (('}' == arry[i]) && ('{' == ch)))
                    {

                        StackPop(ps);
                        i++;
                        continue;
                    }
                    else
                    {
                        printf("括号匹配出错!\n");
                        return;
                    }
                }
            }
        }
        else   //不是括号,不用操作,直接向后走
        {
            i++;
        }
    }
    if (!StackEmpty(ps))
    {
        printf("左括号比右括号多!\n");
    }
    else
    {
        printf("匹配正确!\n");
    }

}

这里写图片描述
test.c//测试文件

#include"MatchBrackets.h"

int main()
{
    Stack s;
    int sz = 0;
    StackInit(&s);
    char a[] = "(())abc{[(])}";//左右括号次序匹配不正确
    char b[] = "(()))abc{[]}";//右括号多于左括号
    char c[] = "(()()abc{[]}";//左括号多于右括号
    char d[] = "(())abc{[]()}";//左右括号匹配正确

    sz = strlen(c);

    MatchBrackets(&s, sz, c);

    return 0;
}

这里写图片描述
经测试,运行结果正确。

猜你喜欢

转载自blog.csdn.net/huaijiu123/article/details/81806636