《编程思维与实践》1091.优雅的括号序列
题目
思路
法一:
通过栈直接进行模拟: 左括号入栈 , 右括号出栈.
入栈前提: 栈空或者栈非空但满足小中大括号的内外次序;
出栈前提: 栈非空且满足小中大括号的内外次序.
注意的点:
每组数据判断前应该先重置栈.
法二:
类似栈思想, 将小中大左括号的个数分别用三个指标存着,遍历字符串不断更新指标,
如果中途遇到不合法的括号顺序,则直接跳出循环,最后判断是否遍历完整个字符串且栈空即可.
左括号合法条件(以小括号为例): 无左括号(小中大均无,即栈空) 或者前一位为左中括号 [ ( ) ] 或者前一位为右小括号 ( )( ) ;
右括号合法条件(以小括号为例): 左小括号不为0或者前一位为左小括号 ( )( ) 或者前一位为右大括号 ( { } ) ;
注意的点:
右括号第一个合法条件不能为非字符串首位, 反例: [ ] ) ( .
代码
法一(栈模拟):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char stack[101];
void pop() //出栈
{
int len=strlen(stack);
stack[len-1]='\0';
}
void push(char ch) //入栈
{
int len=strlen(stack);
stack[len]=ch;
stack[len+1]='\0';
}
int main()
{
int T;
scanf("%d",&T);
for(int t=0;t<T;t++)
{
char s[101];
scanf("%s",s);
int i;
stack[0]='\0'; //重置栈
for(i=0;i<strlen(s);i++)
{
int len=strlen(stack);
if(s[i]=='(')
{
if(len!=0&&stack[len-1]!='[')
{
break;
}
else
{
push(s[i]);
}
}
else if(s[i]=='[')
{
if(len!=0&&stack[len-1]!='{')
{
break;
}
else
{
push(s[i]);
}
}
else if(s[i]=='{')
{
if(len!=0&&stack[len-1]!='(')
{
break;
}
else
{
push(s[i]);
}
}
else if(s[i]==')')
{
if(len==0||stack[len-1]!='(')
{
break;
}
else
{
pop();
}
}
else if(s[i]==']')
{
if(len==0||stack[len-1]!='[')
{
break;
}
else
{
pop();
}
}
else if(s[i]=='}')
{
if(len==0||stack[len-1]!='{')
{
break;
}
else
{
pop();
}
}
}
if(i==strlen(s))
{
if(strlen(stack)==0) //栈空
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
else
{
printf("No\n");
}
}
return 0;
}
法二(迭代):
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
int T;
scanf("%d",&T);
for(int t=0;t<T;t++)
{
char s[101];
scanf("%s",s);
int flag1=0,flag2=0,flag3=0; //小 中 大
int i;
for(i=0;i<strlen(s);i++)
{
if(s[i]=='(')
{
if((flag1==0&&flag2==0&&flag3==0)||s[i-1]=='['||s[i-1]==')')
{
flag1++;
}
else
{
printf("No\n");
break;
}
}
else if(s[i]=='[')
{
if((flag1==0&&flag2==0&&flag3==0)||s[i-1]=='{'||s[i-1]==']')
{
flag2++;
}
else
{
printf("No\n");
break;
}
}
else if(s[i]=='{')
{
if((flag1==0&&flag2==0&&flag3==0)||s[i-1]=='('||s[i-1]=='}')
{
flag3++;
}
else
{
printf("No\n");
break;
}
}
else if(s[i]==')')
{
if(flag1!=0&&(s[i-1]=='('||s[i-1]=='}'))
{
flag1--;
}
else
{
printf("No\n");
break;
}
}
else if(s[i]==']')
{
if(flag2!=0&&(s[i-1]=='['||s[i-1]==')'))
{
flag2--;
}
else
{
printf("No\n");
break;
}
}
else if(s[i]=='}')
{
if(flag3!=0&&(s[i-1]=='{'||s[i-1]==']'))
{
flag3--;
}
else
{
printf("No\n");
break;
}
}
}
if(i==strlen(s))
{
if(flag1==0&&flag2==0&&flag3==0)
{
printf("Yes\n");
}
else
{
printf("No\n");
}
}
}
return 0;
}