栈之括号配对

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

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

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

#include<stdio.h>
#include <stdlib.h>
#define N 100

typedef 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 10000

int 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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值