数据结构 栈与队列(一) 括号匹配

数据结构(四)

学习数据结构与算法过程中的心得体会以及知识点的整理,方便我自己查找,也希望可以和大家一起交流。

—— 括号匹配 ——

1.题目描述

Candela是一名漫画家,她有一个奇特的爱好,就是在纸上画括号。这一天,刚刚起床的Candela画了一排括号序列,其中包含小括号()、中括号[]和大括号{},总长度为N。这排随意绘制的括号序列显得杂乱无章,于是Candela定义了什么样的括号序列是美观的:
(1) 空的括号序列是美观的;
(2) 若括号序列A是美观的,则括号序列(A)、[A]、{A}也是美观的;
(3)若括号序列A、B都是美观的,则括号序列AB也是美观的; 例如 (){[]}() 是美观的括号序列,而 )({)[}]( 则不是。
现在Candela想知道她画出的括号序列是不是美观的。你能帮帮她吗?

1.1输入

一个括号序列,长度不超过10000。

1.2输出

如果它是美观的,输出Yes,否则输出No。

1.3样例输入和输出

样例输入
{ } ( ) { [ ] } ( )
样例输出
Yes

2.代码实现

c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef char ElemType;

typedef struct{
     //存储元素的数组
     ElemType *base;
     //栈顶指针
     int top;
     //当前分配的存储容量( 以sizeof(ElemType)为单位 )
     int capacity;

}Stack;
//初始化一个空栈。空栈拥有10000个元素的空间,栈顶值为 -1
void init(Stack *pStack)
{
    pStack->base=(ElemType*)malloc(10*sizeof(ElemType));
    pStack->capacity=10;
    pStack->top=-1;
}
//把x入栈
void push(Stack *pStack,ElemType x)
{
    //如果输入的元素即将超出栈的最大限制,那么进行扩容。
    if(pStack->top==pStack->capacity-1)
    {
        //以原来容量的两倍进行扩容.
        pStack->capacity*=2;
        ElemType*b=(ElemType*)malloc(pStack->capacity*sizeof(ElemType));
        //复制数据到新的扩容后的栈中数组
        for(int e=0;e<=pStack->top;e++)
        {
            b[e]=pStack->base[e];
        }
        free(pStack->base);
        pStack->base=b;
    }
    //如果输入的元素没有超出栈的最大限制,那么将元素压栈
    pStack->base[++pStack->top]=x;
}
//返回当前栈顶元素的值
ElemType top(Stack *pStack)
{
    ElemType f=pStack->base[pStack->top];
    return f;
}
//当前栈顶元素出栈
void pop(Stack *pStack)
{
    pStack->top--;
}
//判断是否栈空,若空则返回 true,否则返回 false
bool empty(Stack *pStack)
{
    if(pStack->top==-1)
        return true;
    else
        return false;
}
//清空分配给栈的存储空间
void destroy(Stack *pStack)
{
    free(pStack->base);
    free(pStack);
}
int main(void)
{
    char c[10000];
    Stack *pStack;
    pStack=(Stack*)malloc(sizeof(Stack));
    init(pStack);
    bool flag=true;
    gets(c);
    for(int i=0;c[i]!='\0';i++)
        {
            if(c[i]=='('||c[i]=='['||c[i]=='{')
                push(pStack,c[i]);

            if(c[i]==')'||c[i]==']'||c[i]=='}')
            {
                if(empty(pStack))
                {
                    printf("No\n");
                    flag = false;
                    break;
                }
                else
                {
                    if((c[i]==')'&&pStack->base[pStack->top]=='(')||
                       (c[i]==']'&&pStack->base[pStack->top]=='[')||
                       (c[i]=='}'&&pStack->base[pStack->top]=='{'))
                       {
                            pop(pStack);
                            continue;
                       }
                    else
                       {
                           printf("No\n");
                           flag=false;
                           break;
                       }
                }
            }
        }
        if(flag==true)
        {
            if(empty(pStack))
                printf("Yes\n");
            else
                printf("No\n");
        }
        destroy(pStack);
    return 0;
}

3.代码说明

这道题虽然说什么美观的括号,但其实就是利用栈实现括号的匹配,那我们首先就要搞清楚括号匹配和不匹配的类型:
1.==匹配的类型就一种==,我们利用栈的先进后出的特性,对括号从最内侧进行匹配,如果到最后一个元素输入后,整个栈中没有元素(匹配后元素就直接出栈删除)的话,就是匹配的,输出“Yes”。
2.==不匹配的类型有三种==
2.1左括号多余,也就是说在输入数据结束后,最后一个元素是括号的左半部分“(”,“{”,“[”。那么这个时候就是输出“No”。
2.2右括号多余,也就是说在输入数据结束后,最后一个元素是括号的右半部分“)”,“}”,“]”。那么这个时候就是输出“No”。
2.3括号不匹配,也就是说在输入数据结束后,栈内元素的括号不能相互匹配,例如:“(}”,“{[”,“[{)”。那么这个时候就是输出“No”。
3.其实==大体思路==就是每输入一个数据就对前一个数据进行匹配,如果匹配成功就一起出栈,如果到最后栈内没有数据了,那就是yes,反之就是No。
4.具体写第二条是因为,有些题目会要求细分为具体不匹配的原因,例如下面这题:

描述

假设表达式中只包含三种括号:圆括号、方括号和花括号,它们可相互嵌套,如([{}])或({[][()]})等均为正确的格式,而{[]})}或{[()]或([]}均为不正确的格式.
输入一串括号
如果输入的右括号多余,输出:Extra right brackets
如果输入的左括号多余,,输出:Extra leftbrackets
如果输入的括号不匹配,输出:Brackets not match
如果输入的括号匹配,输出:Brackets match

输入

{{{{)))

输出

Brackets not match

样例输入

{([)]}

样例输出

Brackets not match

这个时候我们只需要把上面的代码稍微改一下输出就可以了

c

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

typedef char ElemType;

typedef struct{

     ElemType *base; //存储元素的数组

     int top;//栈顶指针

     int capacity; //当前分配的存储容量( 以sizeof(ElemType)为单位 )

}Stack;

void init(Stack *pStack) //初始化一个空栈。空栈拥有10个元素的空间,栈顶值为 -1
{
    pStack->base =(ElemType*)malloc(10*sizeof(ElemType));
    pStack->capacity = 10;
    pStack->top = -1;
}

void push(Stack *pStack, ElemType x)//把 x 入栈
{
    if(pStack->top == pStack->capacity - 1)
    {
        pStack->capacity*=2;
        ElemType*b = (ElemType*)malloc(pStack->capacity*sizeof(ElemType));
        for(int e=0;e<=pStack->top;e++)
        {
            b[e] = pStack->base[e];
        }
        free(pStack->base);
        pStack->base = b;
    }
    pStack->base[++pStack->top] = x;
}

ElemType top(Stack *pStack)//返回当前栈顶元素的值
{
    ElemType f = pStack ->base[pStack->top];
    return f;
}

void pop(Stack *pStack)//当前栈顶元素出栈
{
    pStack->top--;
}

bool empty(Stack *pStack)//如果栈空,则返回 true,否则返回 false
{
    if(pStack->top == -1)
        return true;
    else
        return false;
}

void destroy(Stack *pStack)//清空分配给栈的存储空间
{
    free(pStack->base);
    free(pStack);
}

int main(void)
{
    char c[31];
    Stack *pStack;
    pStack = (Stack*)malloc(sizeof(Stack));
    init(pStack);
    bool flag = true;
    gets(c);
    for(int i=0;c[i]!='\0';i++)
        {
            if(c[i] == '('||c[i] == '['||c[i] == '{')
                push(pStack,c[i]);

            if(c[i] == ')'||c[i] == ']'||c[i] == '}')
            {
                if(empty(pStack))
                {
                //改动1
                    printf("Extra right brackets\n");
                    flag = false;
                    break;
                }
                else
                {
                    if((c[i] == ')'&&pStack->base[pStack->top] == '(')||
                       (c[i] == ']'&&pStack->base[pStack->top] == '[')||
                       (c[i] == '}'&&pStack->base[pStack->top] == '{'))
                       {
                            pop(pStack);
                            continue;
                       }
                    else
                       {
                       //改动2
                           printf("Brackets not match\n");
                           flag = false;
                           break;
                       }
                }
            }
        }
        if(flag == true)
        {
            if(empty(pStack))
            //改动3
                printf("Brackets match\n");
            else
            //改动4
                printf("Extra left brackets\n");
        }
        destroy(pStack);
    return 0;
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,163评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,301评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,089评论 0 352
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,093评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,110评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,079评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,005评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,840评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,278评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,497评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,667评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,394评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,980评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,628评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,649评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,548评论 2 352

推荐阅读更多精彩内容