问题说明:

假设数学表达式中允许包含两种括号:圆括号“()”和方括号“[]”,嵌套顺序任意。

正确的嵌套模式:( [ ] ( ) )、[ ( [ ] [ ] ) ]

正确的表达式例:(a+b)[c*(d-e)]

错误的嵌套模式:[ ( ] )、( ( ) ]

比如,在处理表达式(A)时

(A)  4+(2+8)*[5/(9-7)]

有以下步骤:

(1)检测到第一个括号“(”;

(2)检测到第二个括号“)”,说明子表达式 “4+(2+8)” 已完成匹配;

(3)检测到第三个括号“[”;

(4)检测到第四个括号“(”,与(3)中的括号不匹配,但由于同是左括号,可以继续匹配;

(5)检测到第五个括号“)”,由括号的作用可知,后来的括号比先来的括号优先级高,因此与(4)中括号匹配;

(6)检测到第六个括号“]”,由于原来优先级更高的括号已完成,因此与(3)中括号匹配。至此所有括号匹配完成。

解决方案:

可以看出,匹配成功的条件很简单:每一个检测到的括号与已检测到的优先级最高的括号都匹配。

匹配失败的条件:

(1)检测到与已检测到的优先级最高的括号不匹配的括号;

(2)扫描完整个表达式,还是有已检测到的括号没有完成匹配;

由于栈具有“先进后出”的特点,能很好地表现优先级这个性质,因此可以用栈来存储已经检测到的括号。

以(A)为例:

有以下步骤:

(1)检测到第一个括号“(”,进栈;

(2)检测到第二个括号“)”,进栈。子表达式 “4+(2+8)” 完成匹配,匹配的括号都出栈;

(3)检测到第三个括号“[”,进栈;

(4)检测到第四个括号“(”,进栈。与(3)中的括号不匹配,但由于同是左括号,可以继续匹配;

(5)检测到第五个括号“)”,进栈。由括号的作用可知,后来的括号比先来的括号优先级高,因此与(4)中括号匹配,匹配的括号都出栈;

(6)检测到第六个括号“]”,进栈。由于原来优先级更高的括号已完成,因此与(3)中括号匹配。匹配的括号都出栈,至此所有括号匹配完成。

需要注意的是,第一个括号进栈时,没有比较对象,因此需要特别处理。

判断函数 judge () 如下:

 1 Status judge(Stack *S)
2 {
3 //进行表达式的输入和判断
4 SElemType *p;
5 char n;
6
7 scanf("%c",&n); //第一个括号的检测
8 while(n!='(' && n!='[') //忽略数字等其他符号,直到输入括号
9 {
10 if(n==')' || n==']' || n=='#') return FALSE; //若为')'或']',则表明不匹配。'#'用于结束输入
11 scanf("%c",&n);
12 }
13
14 if(n=='(' || n=='[') Push(S,n); //检测到左括号,进栈
15 scanf("%c",&n);
16 while(n!='#') //'#'用于结束输入
17 {
18 if(n=='(' || n==')' || n=='[' || n==']')
19 {
20 p=S->top;
21 Push(S,n);
22 if(*(p-1)=='(') //与前一个括号比较
23 {
24 if(*p==')')
25 {
26 printf("%c\n",Pop(S));
27 printf("%c\n",Pop(S));
28 }
29 else if(*p==']') return FALSE;
30 }
31 else if(*(p-1)=='[')
32 {
33 if(*p==']')
34 {
35 printf("%c\n",Pop(S));
36 printf("%c\n",Pop(S));
37 }
38 else if(*p==')') return FALSE;
39 }
40 }
41 scanf("%c",&n);
42 }
43 if(S->top==S->base) return TRUE; //栈内没有元素时,说明匹配
44 else return FALSE;
45 }

源代码如下:

#include <stdio.h>
#include <stdlib.h>
#define INIT_SIZE 10
#define INCREMENT 5 #define OVERFLOW -2
#define FALSE 0
#define OK 1
#define TRUE 1
#define ERROR 0 typedef char SElemType;
typedef int Status;
typedef struct stack{
SElemType *base;
SElemType *top;
int stacksize;
}Stack; Status InitStack(Stack *S)
{
//初始化栈
S->base=(SElemType *)malloc(INIT_SIZE*sizeof(SElemType));
if(!S->base) exit(OVERFLOW);
S->top=S->base;
S->stacksize=INIT_SIZE;
return OK;
} Status Push(Stack *S,char e)
{
//入栈
if(S->top-S->base>=S->stacksize){ //栈满,重新分配内存
S->base=(SElemType *)realloc(S->base,(INIT_SIZE+INCREMENT)*sizeof(SElemType));
if(!S->base) exit(OVERFLOW);
S->top=S->base+S->stacksize;
S->stacksize+=INCREMENT;
}
*S->top++=e;
return OK;
} char Pop(Stack *S)
{
//出栈
char e; if(S->top==S->base) return ERROR; //栈空,出错
e=*(--S->top);
return e;
} Status judge(Stack *S)
{
//进行表达式的输入和判断
SElemType *p;
char n; scanf("%c",&n); //第一个括号的检测
while(n!='(' && n!='[') //忽略数字等其他符号,直到输入括号
{
if(n==')' || n==']' || n=='#') return FALSE; //若为')'或']',则表明不匹配。'#'用于结束输入
scanf("%c",&n);
} if(n=='(' || n=='[') Push(S,n); //检测到左括号,进栈
scanf("%c",&n);
while(n!='#') //'#'用于结束输入
{
if(n=='(' || n==')' || n=='[' || n==']')
{
p=S->top;
Push(S,n);
if(*(p-1)=='(') //与前一个括号比较
{
if(*p==')')
{
printf("%c\n",Pop(S));
printf("%c\n",Pop(S));
}
else if(*p==']') return FALSE;
}
else if(*(p-1)=='[')
{
if(*p==']')
{
printf("%c\n",Pop(S));
printf("%c\n",Pop(S));
}
else if(*p==')') return FALSE;
}
}
scanf("%c",&n);
}
if(S->top==S->base) return TRUE; //栈内没有元素时,说明匹配
else return FALSE;
} int main()
{
Stack Sta;
Stack *S=&Sta; printf("INITIALIZING...\n");
if(InitStack(S)) printf("DONE!\n"); printf("enter an expression(stop by '#'):\n");
if(judge(S)==1) printf("It's True!");
else printf("It's False\n"); return 0;
}

source

栈的应用:表达式括号匹配检测(C)的更多相关文章

  1. luoguP1739 表达式括号匹配 x

    P1739 表达式括号匹配 题目描述 假设一个表达式有英文字母(小写).运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符.请编写一个程序检查表达式中的左右圆括号是否匹配,若匹 ...

  2. C++括号匹配检测(用栈)

    输入一串括号,包括圆括号和方括号,()[],判断是否匹配,即([]())或[([][])]为匹配的正确的格式,[(])或([())为不匹配的格式. #include<iostream> # ...

  3. java:数据结构(二)栈的应用(括号匹配)

    一.什么是括号匹配: 括号匹配就是利用计算机辨别表达式里面的括号是否书写成功 例如: {()((a)) }这就是一个正确 (()()   这就是一个错误的 二.括号匹配的算法: 众所周知,括号分为花括 ...

  4. 洛谷 P1739 表达式括号匹配

    题目链接https://www.luogu.org/problemnew/show/P1739 题目描述 假设一个表达式有英文字母(小写).运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为 ...

  5. P1739_表达式括号匹配(JAVA语言)

    思路:刚开始想用stack,遇到'('就push,遇到')'就pop,后来发现其实我们只需要用到栈里'('的个数,所以我们用一个变量统计'('的个数就好啦~ 题目描述 假设一个表达式有英文字母(小写) ...

  6. C++学习(三十一)(C语言部分)之 栈和队列(括号匹配示例)

    括号匹配测试代码笔记如下: #include<stdio.h> #include<string.h> #include <stdlib.h> #define SIZ ...

  7. python栈--字符串反转,括号匹配

    栈的实现: # 定义一个栈类 class Stack(): # 栈的初始化 def __init__(self): self.items = [] # 判断栈是否为空,为空返回True def isE ...

  8. java版括号匹配检测

    做一个空栈,读入字符直到结尾.如果读入一个封闭符号,空栈时报错;非空时弹出栈尾字符,如果不匹配则报错.否则读入为开放字符,压入栈中.最后如果栈空,返回true. 其中用到MyStack类,详情请见 p ...

  9. (栈 注意格式)P1739 表达式括号匹配 洛谷

    题目描述 假设一个表达式有英文字母(小写).运算符(+,—,*,/)和左右小(圆)括号构成,以“@”作为表达式的结束符.请编写一个程序检查表达式中的左右圆括号是否匹配,若匹配,则返回“YES”:否则返 ...

随机推荐

  1. TestLink在线Excel用例转换xml

    [原文链接]:https://blog.tecchen.tech ,博文同步发布到博客园. 由于精力有限,对文章的更新可能不能及时同步,请点击上面的原文链接访问最新内容. 欢迎访问我的个人网站:htt ...

  2. Mac支持的网络游戏有哪些?怎么支持Windows游戏?

    "游戏是这个世界上唯一能和女性争夺男朋友的东西(/滑稽,有不少女生也喜欢玩游戏)."虽然只是一句玩笑话,不过也可以看出游戏对大多数男生来说是必不可少的一项娱乐活动了.而网络游戏是游 ...

  3. Centos7 安装python3 pip3

    Centos7 安装python3 pip3 安装python3.6 安装 python36   yum install python36 -y   查看版本 安装完成,查看一下python版本是否正 ...

  4. 对Tarjan——有向图缩点算法的理解

    开始学tarjan的时候,有关无向图的割点.桥.点双边双缩点都比较容易地理解了,唯独对有向图的缩点操作不甚明了.通过对luoguP2656_采蘑菇一题的解决,大致搞清了tarjan算法的正确性. 首先 ...

  5. HDU 4920 Matrix multiplication 题解(内存访问连续性/卡常)

    题目链接 题目大意 多组输入,给你两个n×n的矩阵,要你求他们相乘%3的值 题目思路 这个题目主要是要了解内存访问连续化,要尽量每次访问连续的内存 所以第一种方法会超时,第二种则AC.一种卡常技巧 代 ...

  6. 三. Vue组件化

    1. 认识组件化 1.1 什么是组件化 人面对复杂问题的处理方式 任何一个人处理信息的逻辑能力都是有限的,所以当面对一个非常复杂的问题时我们不太可能一次性搞定一大堆的内容. 但是我们人有一种天生的能力 ...

  7. Dotnet Core下的Channel, 你用了吗?

    今天给大家分享一个微软官方的好东西:Channel.   前言 今天给大家分享一个微软官方的生产者/消费者方案的特性解决:Channel. Channel在System.Threading.Chann ...

  8. 20190620_二次开发BarTender打印机时,未能解析主引用“Seagull.BarTender.Print, Version=1.0.0.0, Culture=neutral, processorArchitecture=x86”

    错误提示: 严重性 代码 说明 项目 文件 行 禁止显示状态警告 未能解析主引用"Seagull.BarTender.Print, Version=1.0.0.0, Culture=neut ...

  9. 第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解

    上节介绍了__new__()方法这个比构造方法还重要的方法的语法,本节通过案例来详细剖析__new__()方法的细节以及它与构造方法之间的关系. 一.    案例说明 本节以圆Cir类为例来说明,为了 ...

  10. PyQt(Python+Qt)学习随笔:QTabWidget选项卡部件外观展示类属性elideMode、documentMode、tabBarAutoHide、tabShape介绍

    QTabWidget的外观展示类属性包括tabPosition.tabShape.elideMode.usesScrollButtons.documentMode.tabBarAutoHide和ico ...