多类型括号匹配
设有算数表达式,其中包含有大括号“{}”、中括号“[]”、小括号“()”,试编写一个递归函数,判断表达式中的括号是否匹配。
#include<bits/stdc++.h>
using namespace std;
//s表示算术表达式的字符串,pos表示现在检测到的位置,初始调用时为-1,count表示目前需要匹配的括号类型,初始调用时为0
int bracket(char *s,int pos,int count)
{
if (pos!=-1&&s[pos]=='\0')
//位置合法时判断字符串是否检测结束
{
//count不为0,表示仍有左括号需要匹配,匹配失败
if(count!=0)return -1;
//count为0,表示所有左括号都已经成功匹配右括号,匹配成功
else return 0;
}
if(pos==-1||s[pos]=='('||s[pos]=='['||s[pos]=='{'){
//判断是否为起始位置或是左括号
int cnt=0;
//不同左括号需判断括号类型
if(pos==-1) cnt=0;
else if (s[pos]=='(') cnt=1;
else if (s[pos]=='[') cnt=2;
else if (s[pos]=='{') cnt=3;
int x=pos+1;
//当目前左括号未找到其对应的右括号,或栈中为空但字符串还没有完全检测时
while(true){
//递归搜索位置为x的字符,初始为pos+1
int loc=bracket(s,x,cnt);
//回溯后的结果为-1,表明该左括号并未找到对应的右括号,匹配失败
if(loc==-1) return -1;
// 栈中为空并且字符串已经全部检测,匹配成功
if(loc==0) return 0;
//判断回溯后的结果所在的字符s[loc]是否与当前字符s[pos]匹配,若匹配,则表明退出该循环,回溯到上一个左括号
if(pos!=-1&&((s[pos]=='('&&s[loc]==')')||(s[pos]=='['&&s[loc]==']')||(s[pos]=='{'&&s[loc]=='}'))){
return loc+1;
}
//如果 s[loc]与s[pos]不匹配,或者已经回到起点,则应从loc的位置开始继续往后搜索
x=loc;
}
}else if(s[pos]==')'||s[pos]==']'||s[pos]=='}'){
//判断当前字符是否是右括号
//判断右括号是否与当前应匹配的左括号对应,如果对应,返回当该字符位置
if (s[pos]==')'&&count==1){
return pos;
}
if (s[pos]==']'&&count==2) {
return pos;
}
if (s[pos]=='}'&&count==3){
return pos;
}
//不对应,匹配失败
return -1;
}else{
//数字字符不影响操作,继续向后搜索
return bracket(s,pos+1,count);
}
}
int main()
{
char s[]="[]";
printf("%d\n",bracket(s,-1,0));
}
备注:其实可以在函数中用一个vector存放遍历到的所有左括号的类型,然后递归检查,会简单很多。这种写法主要是想尝试不使用数组存放目前检索到所有的左括号并完成括号匹配。