题目描述:
设表达式中包含三种括号:圆括号,方括号和花括号,它们可以互相嵌套,如([{}])和{{()[]}}等均为正确的格式,而{[(])}和{(}均为不正确的格式。
算法思想:
- 检验算法中可设置一个栈
- 每读入一个括号,若是左括号,则直接入栈,等待相匹配的同类右括号
- 若读入的是右括号,且与当前栈顶的左括号同类型,则二者匹配,将栈顶的左括号出栈,否则属于不合法的情况。
- 另外,如果输入的序列已读完,而栈中的仍有等待匹配的的左括号
- 或读入了一个右括号,而栈中已无等待匹配的同类型左括号,均属于不合法的情况。
- 当输入序列和栈同时变为空时,说明所有括号完全匹配。
按照书上的提示,我们得先写出相关的函数,再将他们结合起来就可以组成判断的函数,代码如下:
#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