栈之括号配对

来源:互联网 发布:域名注册通讯地址 编辑:程序博客网 时间:2024/05/16 14:51

题目描述:
设表达式中包含三种括号:圆括号,方括号和花括号,它们可以互相嵌套,如([{}])和{{()[]}}等均为正确的格式,而{[(])}和{(}均为不正确的格式。
算法思想:

  1. 检验算法中可设置一个栈
  2. 每读入一个括号,若是左括号,则直接入栈,等待相匹配的同类右括号
  3. 若读入的是右括号,且与当前栈顶的左括号同类型,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况。
  4. 另外,如果输入的序列已读完,而栈中的仍有等待匹配的的左括号
  5. 或读入了一个右括号,而栈中已无等待匹配的同类型左括号,均属于不合法的情况。
  6. 当输入序列和栈同时变为空时,说明所有括号完全匹配。

按照书上的提示,我们得先写出相关的函数,再将他们结合起来就可以组成判断的函数,代码如下:

#include<stdio.h>#include <stdlib.h>#define N 100typedef struct  bracket{    char data;    struct bracket *next;}LinkBracketNode, *LinkBracket;void BracketMatch(char *str); //检测函数void InitBracket(LinkBracket *S);//初始化void PushBracket(LinkBracket S,char ch);//入栈void PopBracket(LinkBracket S,char *ch);//出栈int IsEmpty(LinkBracket S);//判空void GetTop(LinkBracket S,char *ch);//取栈顶元素int Match(char a,char b);//匹配int main(void){    char str[N];    scanf("%s", str);    BracketMatch(str);    getchar();    getchar();    return 0;}void BracketMatch(char *str){    LinkBracket S = NULL;    int i;    char ch;    InitBracket(&S);    for (i = 0; str[i] != '\0'; i++)    {        switch (str[i])        {        case '(':        case '[':        case '{':            PushBracket(S, str[i]);            break;        case ')':        case ']':        case '}':            if (IsEmpty(S))            {                printf("ÓÒÀ¨ºÅ¶àÓà\n");                getchar();                getchar();                exit(0);            }            else            {                GetTop(S, &ch);                if (Match(ch, str[i]))//用match判断连个括号是否匹配                    PopBracket(S, &ch);//已匹配括号出栈                else                {                    printf("\n¶ÔÓ¦µÄ×óÓÒÀ¨ºÅ²»Í¬Àà\n");                    getchar();                    getchar();                    exit(0);                }            }        }/*switch*/    }/*for*/    if (IsEmpty(S))    {        printf("\nÀ¨ºÅÆ¥Åä\n");    }    else    {        printf("\n×óÀ¨ºÅ¶àÓà\n");    }}void InitBracket(LinkBracket *S){    (*S) = (LinkBracketNode *)malloc(sizeof(LinkBracketNode));    (*S)->next = NULL;}void PushBracket(LinkBracket S, char ch){    LinkBracketNode *p = NULL;    p = (LinkBracketNode *)malloc(sizeof(LinkBracketNode));    p->data = ch;    p->next = S->next;    S->next = p;}void PopBracket(LinkBracket S, char *ch){    LinkBracketNode *p = S->next;     if (p->data==*ch)    {        S->next = p->next;    }    free(p);}int IsEmpty(LinkBracket S){    if (S->next==NULL)    {        return 1;    }    else    {        return 0;    }}void GetTop(LinkBracket S, char *ch){    *ch = S->next->data;}int Match(char a, char b){    switch (a)    {    case '(':        if (b==')')        {             return 1;        }        else        {             return 0;        }        break;    case '[':        if (b == ']')        {            return 1;        }        else        {            return 0;        }        break;    case '{':        if (b == '}')        {            return 1;        }        else        {            return 0;        }        break;    }}

这是利用栈的方式来解决的,思路清晰,但函数较多,下面这是我做南阳ACM的括号匹配的题,当时还没学数据结构,便直接用的循环,判断语句。

题目如下:
括号配对问题
时间限制:3000 ms | 内存限制:65535 KB
难度:3
描述
现在,有一行括号序列,请你检查这行括号是否配对。
输入
第一行输入一个数N(0

#include<stdio.h>#include<string.h>#define N 100#define M 10000int main(void){    int n,count[N],count2[N]= {0},count1=0,i,j,a=0,b=0;    char bracket[N][M],c,c1='(',c2='[',c3=')',c4=']';    scanf("%d",&n);    getchar();    for(i=0; i<n; i++)    {        for(j=0; j<M; j++)        {            c=getchar();            if(c=='\n')            {                break;            }            else            {                bracket[i][j]=c;            }            count1++;//对输入的字符的计数        }        count[i]=count1;        count1=0;    }    for(i=0; i<n; i++)//外层循环实现的是又几组测试数据    {        if(count[i]%2!=0)        {            count2[i]=1;            continue;        }        if(count[i]<=2)        {            if(bracket[i][0]==c1)            {                if(bracket[i][1]!=c3)                {                    count2[i]=1;                }            }            if(bracket[i][0]==c2)            {                if(bracket[i][1]!=c4)                {                    count2[i]=1;                }            }            if(bracket[i][0]==c3)            {                count2[i]=1;            }            if(bracket[i][0]==c4)            {                count2[i]=1;            }        }        else        {            for(j=0; j<(count[i]/2); j++)            {                if(bracket[i][j]==c1)                {                    if(bracket[i][j+1]==c3)//相邻的情况                    {                        count[i]++;                    }                    else                    {                        a=1;                    }                    if(bracket[i][count[i]-j-1]==c3)//不相邻的情况                    {                        b=0;                    }                    if(a+b==2)                    {                        count2[i]=1;                    }                    else                    {                        count2[i]=0;                    }                }                if(bracket[i][j]==c2)                {                    if(bracket[i][j+1]==c4)                    {                        count[i]++;                    }                    else                    {                        a=1;                    }                    if(bracket[i][count[i]-j-1]!=c4)                    {                        b=1;                    }                    if(a+b==2)                    {                        count2[i]=1;                    }                    else                    {                        count2[i]=0;                    }                }            }        }    }    for(i=0; i<n; i++)    {        if(count2[i]==0)        {            printf("Yes\n");        }        else        {            printf("No\n");        }    }    return 0;}

这篇代码主要是对括号的在字符串中的序列来考虑的!

两种方法各有各的优点吧!栈,思路清晰,但过程复杂,函数较多;普通的则代码简单,但思路叫为复杂!

                                -----2016.4.18于电子楼311
1 0