第五周项目3-括号的匹配

问题及代码:
/*  
* Copyright(c) 2016, 烟台大学计算机与控制工程学院  
* All rights reserved.  
* 文件名称:  
* 作    者:孙子晴  
* 完成日期:2016年10月8日  
* 版 本 号:v1.0  
*  
* 问题描述: 假设表达式中允许三种括号:圆括号、方括号和大括号。编写一个算法,判断表达式中的各种左括号是否与右括号匹配。  
* 输入描述:2+(3+4)*[2+{[3]}-8   2+(3+4*[2)+{[3]}-8, 
* 程序输出:匹配是否成功  
*/    

listack.h:

#ifndef LISTACK_H_INCLUDED  
#define LISTACK_H_INCLUDED  
typedef char ElemType;  
typedef struct linknode  
{  
    ElemType data;              //数据域  
    struct linknode *next;      //指针域  
} LiStack;                      //链栈类型定义  
  
void InitStack(LiStack *&s);  //初始化栈  
void DestroyStack(LiStack *&s);  //销毁栈  
int StackLength(LiStack *s);  //返回栈长度  
bool StackEmpty(LiStack *s);  //判断栈是否为空  
void Push(LiStack *&s,ElemType e);  //入栈  
bool Pop(LiStack *&s,ElemType &e);  //出栈  
bool GetTop(LiStack *s,ElemType &e);  //取栈顶元素  
void DispStack(LiStack *s);  //输出栈中元素  
  
#endif // LISTACK_H_INCLUDED  
listack.cpp

#include <malloc.h>  
#include "listack.h"  
  
void InitStack(LiStack *&s)  //初始化栈  
{  
    s=(LiStack *)malloc(sizeof(LiStack));  
    s->next=NULL;  
}  
  
void DestroyStack(LiStack *&s)  //销毁栈  
{  
    LiStack *p=s->next;  
    while (p!=NULL)  
    {  
        free(s);  
        s=p;  
        p=p->next;  
    }  
    free(s);    //s指向尾结点,释放其空间  
}  
  
int StackLength(LiStack *s)  //返回栈长度  
{  
    int i=0;  
    LiStack *p;  
    p=s->next;  
    while (p!=NULL)  
    {  
        i++;  
        p=p->next;  
    }  
    return(i);  
}  
  
bool StackEmpty(LiStack *s)  //判断栈是否为空  
{  
    return(s->next==NULL);  
}  
  
void Push(LiStack *&s,ElemType e)  //入栈  
{  
    LiStack *p;  
    p=(LiStack *)malloc(sizeof(LiStack));  
    p->data=e;              //新建元素e对应的节点*p  
    p->next=s->next;        //插入*p节点作为开始节点  
    s->next=p;  
}  
  
bool Pop(LiStack *&s,ElemType &e)  //出栈  
{  
    LiStack *p;  
    if (s->next==NULL)      //栈空的情况  
        return false;  
    p=s->next;              //p指向开始节点  
    e=p->data;  
    s->next=p->next;        //删除*p节点  
    free(p);                //释放*p节点  
    return true;  
}  
  
bool GetTop(LiStack *s,ElemType &e)  //取栈顶元素  
{  
    if (s->next==NULL)      //栈空的情况  
        return false;  
    e=s->next->data;  
    return true;  
}  
  
void DispStack(LiStack *s)  //输出栈中元素  
{  
    LiStack *p=s->next;  
    while (p!=NULL)  
    {  
        printf("%c ",p->data);  
        p=p->next;  
    }  
    printf("\n");  
}  


 main.cpp: 

#include <stdio.h>  
#include <string.h>  
#include "listack.h"  
bool match1(ElemType exp[],int n)  
{  
    int i=0;  
    char e;  
    bool match=true;  
    LiStack *st;  
    InitStack(st);                //初始化栈  
    while(i<n && match)           //扫描exp中的所有字符  
    {  
        if(exp[i]=='(')           //当前字符为左括号,进栈  
            Push(st,exp[i]);  
        else if(exp[i]==')')      //当前字符为右括号  
        {  
            if(GetTop(st,e)==true)//能够取出栈顶元素  
            {  
                if(e!='(')        //栈顶元素不为'('时表示不匹配  
                    match=false;  
                else              //匹配,将栈顶元素出栈  
                    Pop(st,e);  
            }  
            else  
                match=false;      //无法取出栈顶元素,表示不匹配  
        }  
        i++;  
    }  
  
    if(!StackEmpty(st))           //最后栈不空时,表示不匹配  
        match=false;  
    DestroyStack(st);             //销毁栈  
    return match;  
}  
bool match2(ElemType exp[],int n)  
{  
    int i=0;  
    char e;  
    bool match=true;  
    LiStack *st;  
    InitStack(st);                //初始化栈  
    while(i<n && match)           //扫描exp中的所有字符  
    {  
        if(exp[i]=='[')           //当前字符为左括号,进栈  
            Push(st,exp[i]);  
        else if(exp[i]==']')      //当前字符为右括号  
        {  
            if(GetTop(st,e)==true)//能够取出栈顶元素  
            {  
                if(e!='[')        //栈顶元素不为'['时表示不匹配  
                    match=false;  
                else              //匹配,将栈顶元素出栈  
                    Pop(st,e);  
            }  
            else  
                match=false;      //无法取出栈顶元素,表示不匹配  
        }  
        i++;  
    }  
    if(!StackEmpty(st))           //最后栈不空时,表示不匹配  
        match=false;  
    DestroyStack(st);             //销毁栈  
    return match;  
}  
bool match3(ElemType exp[],int n)  
{  
    int i=0;  
    char e;  
    bool match=true;  
    LiStack *st;  
    InitStack(st);                //初始化栈  
    while(i<n && match)           //扫描exp中的所有字符  
    {  
        if(exp[i]=='{')           //当前字符为左括号,进栈  
            Push(st,exp[i]);  
        else if(exp[i]=='}')      //当前字符为右括号  
        {  
            if(GetTop(st,e)==true)//能够取出栈顶元素  
            {  
                if(e!='{')        //栈顶元素不为'{'时表示不匹配  
                    match=false;  
                else              //匹配,将栈顶元素出栈  
                    Pop(st,e);  
            }  
            else  
                match=false;      //无法取出栈顶元素,表示不匹配  
        }  
        i++;  
    }  
    if(!StackEmpty(st))           //最后栈不空时,表示不匹配  
        match=false;  
    DestroyStack(st);             //销毁栈  
    return match;  
}  
int main()  
{  
    ElemType a[1000];  
    int n;  
    printf("请输入表达式:");  
    while(gets(a))  
    {  
        n=strlen(a);  
        if(match1(a,n) && match2(a,n) && match3(a,n))  
            printf("匹配正确!\n");  
        else  
            printf("匹配错误!\n");  
    }  
    return 0;  
}  
运行结果:

知识点总结:

链栈的基本操作和应用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
资源包主要包含以下内容: ASP项目源码:每个资源包中都包含完整的ASP项目源码,这些源码采用了经典的ASP技术开发,结构清晰、注释详细,帮助用户轻松理解整个项目的逻辑和实现方式。通过这些源码,用户可以学习到ASP的基本语法、服务器端脚本编写方法、数据库操作、用户权限管理等关键技术。 数据库设计文件:为了方便用户更好地理解系统的后台逻辑,每个项目中都附带了完整的数据库设计文件。这些文件通常包括数据库结构图、数据表设计文档,以及示例数据SQL脚本。用户可以通过这些文件快速搭建项目所需的数据库环境,并了解各个数据表之间的关系和作用。 详细的开发文档:每个资源包都附有详细的开发文档,文档内容包括项目背景介绍、功能模块说明、系统流程图、用户界面设计以及关键代码解析等。这些文档为用户提供了深入的学习材料,使得即便是从零开始的开发者也能逐步掌握项目开发的全过程。 项目演示与使用指南:为帮助用户更好地理解和使用这些ASP项目,每个资源包中都包含项目的演示文件和使用指南。演示文件通常以视频或图文形式展示项目的主要功能和操作流程,使用指南则详细说明了如何配置开发环境、部署项目以及常见问题的解决方法。 毕业设计参考:对于正在准备毕业设计的学生来说,这些资源包是绝佳的参考材料。每个项目不仅功能完善、结构清晰,还符合常见的毕业设计要求和标准。通过这些项目,学生可以学习到如何从零开始构建一个完整的Web系统,并积累丰富的项目经验。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值