目录
一. 题目复现
二. 思路解释
三. 代码实现
一. 题目复现
检查一段C语言代码的小括号( )
、 中括号 [ ]
和大括号{ }
是否匹配
输入格式:
在一行中输入一段C语言代码,长度不超过1000个字符(行末以换行符结束)。
输出格式:
第一行输出左括号的数量和右括号的数量,中间以一个空格间隔。
若括号是匹配的,在第二行打印YES
,否则打印NO
。
二. 思路解释
本题目的为在字符串里实现'['与']' , '('与')' , '{'与'}' 的字符匹配,难点也是这个。
思路过程:
栈有先进后出的特点,本题所设置的一个栈仅对'['与']' , '('与')' , '{'与'}' 的字符进行存、取与查看栈顶操作。如下图为实现过程:
如图,我们假设此时栈顶元素是'[',此时有两种情况:
(1)如果下一个即将入栈的字符c(注意c还没有入栈)是']',则和栈顶的'['匹配,那么可以将栈顶元素'['出栈,当然了字符c既然和栈顶匹配了也不用入栈啦。
(2)如果一个即将入栈的字符c不与此时的栈顶'['匹配,即不是']',则将c入栈,等待下一次匹配。
这样的结果是什么: 每一次匹配成功就有一个符号出栈,当所以字符串都有匹配成功,栈空就是自然而然的事——YES;若最后不是空栈,则说明匹配没有成功——NO。
三. 代码实现
c++:
#include<iostream>
#include<string>
using namespace std;
//栈结构体,以SqStack命名
typedef struct {
char *base;
char *top;
int stacksize;
}SqStack;
bool matchChar(char c,char c0);//匹配c和c0是否匹配,如c='[',c0=']'匹配,
//注意c='[',若c0='}' 或')' 时就不匹配了
void iniStack(SqStack&S,int size);//初始化栈
void popStack(SqStack&S);//出栈
void pushStack(SqStack&S,char celem);//celem入栈
char getStackTop(SqStack&S);//查看栈顶元素,栈内部结构和元素不改变
int main()
{
string cstr;
int stacksize;//本次匹配所需栈的空间,就是输入字符串的长度
int l=0;//记录左括号
int r=0;//记录右括号
SqStack stk;
getline(cin,cstr);//输入字符串
stacksize=cstr.length();//本次匹配所需栈的空间,就是输入字符串的长度
iniStack(stk,stacksize);//初始化栈
for(int i=0;i<cstr.length();i++)
{
if(cstr[i]=='('||cstr[i]=='{'||cstr[i]=='[')//左括号
{
//若遍历到的字符为左括号,绝不可能在一个从左到右([0]到[cstr.length()])遍历的字符串中
//找到匹配,只可能是右括号与栈中存在的左括号匹配,因此左括号不需匹配,直接入栈
l++;//左括号数加一
pushStack(stk,cstr[i]);//入栈
}
else if(cstr[i]=='}'||cstr[i]==']'||cstr[i]==')')//右括号
{
r++;//右括号数加一
if(matchChar(cstr[i],getStackTop(stk)))//将此时的str[i]与此时栈顶元素匹配,匹配成功返回true,反之返回false
{
popStack(stk);//匹配成功即将栈顶元素出栈
}
else
{
pushStack(stk,cstr[i]);//匹配失败即将str[i]入栈
}
}
}
cout<<l<<' '<<r<<endl;
if(stk.base==stk.top)//判断栈空,若栈空,则全部匹配成功,YES
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
return 0;
}
bool matchChar(char c,char c0) {
bool is_match=false;
if(c=='}')
{
if(c0=='{')
is_match=true;
}
else if(c==']')
{
if(c0=='[')
is_match=true;
}
else if(c==')')
{
if(c0=='(')
is_match=true;
}
return is_match;
}
void iniStack(SqStack&S,int size) {
S.base=new char[size];
S.top=S.base;
S.stacksize=size;
}
void popStack(SqStack&S) {
if(S.top==S.base)
cout<<"StackNull,so poperror."<<endl;
S.top--;
}
void pushStack(SqStack&S,char celem) {
if(S.top-S.base==S.stacksize)//判断栈满
cout<<"StackFull,so pusherror."<<endl;
*S.top=celem;
S.top++;
}
char getStackTop(SqStack&S) {
char celem;
if(S.top==S.base)//判断栈空
celem='#';
else
{
S.top--;//先将top指针退回指向栈顶元素
celem=*(S.top);//取栈顶元素
S.top++; //再将top指针恢复
}
//栈的top指针总是指向有元素存储位置的下一个存储位置(较高存储位)
return celem;
}