目录
一. 题目复现
二. 思路解释
三. 代码实现
检查一段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; }