1.什么是括号匹配?
直觉上是这个形式的:((3+5)*8+9)+(5/3-3)
对于计算机而言其主要特征是:
(1)在从左向右读取括号的过程中,左括号数量总是大于等于右括号
(2)同样,从右向左读取时,右括号数量总是大于等于左括号
(3)读取结束时,左右括号相等。
2.算法雏形
(1)我们需要处理掉表达式左侧及右侧的非括号内容,找到左侧和右侧的第一个括号元素。
(2)于是我们可以从第一个左括号开始,对左右括号分别计数,左括号等于右括号时即读取到一个括号复合体(当然可以直接读至表达式的末尾,但为了将一个括号复合体单独提取出,以便对其进行内)容读取,所以我们在此时结束,并对此括号复合体内部,及右边剩余表达式进行相同处理),将其分离开,并对其括号内部及右侧剩余表达式进行相同处理。
以上,便有了递归算法的思想。
3.代码实现
/ / trim()函数处理掉表达式(此处表达式我们用char[]来表示)左侧及右侧的非括号元素,并保留各自括号元素的引用
void trim(const char exp[],int &lo,int& hi){
while( (lo<=hi) && (exp[lo]!= '(' ) &&(exp[lo]!= ')' ) lo++;
while( (lo<=hi) && (exp[hi]!= '(' ) &&(exp[hi]!= ')' ) hi--;
//无括号时lo会大于hi;仅有一个括号时,lo和hi势必有一个此时对应的括号形式错误(如lo本应左括号,却对应了右括号),可以交由后面的函数进行检验
}
/ / divide()函数负责括号复合体的切分工作
int divide(const char exp[],int lo, int hi){
int mi=lo;int crc=1; //记录左括号与右括号之差,显然当差值等于零时即得到一个括号复合体
while( (0<crc)&&(++mi<hi) ){
if( exp[mi]= '(' ) crc++; if ( exp[mi]= ')' ) crc--;}
if(crc>1)return mi+1; //处理左括号过多情况。
return mi;
/ / paren()函数负责将以上操作整合,并实现迭代
bool paren(const char exp[], int lo, int hi) {
trim(exp, lo, hi); if (lo > hi)return true; //对应无括号,返回true
if ( (exp[lo] == ')' ) || (exp[hi] == '(') ) return false; //括号匹配错误时,返回false
int mi = divide(exp, lo, hi); //mi应指向右括号
if (mi > hi) return false; //此时左括号过多,返回false
return paren(exp, lo + 1, mi - 1) && paren(exp, mi + 1, hi); //对括号内部及右侧剩余表达式递归,当且仅当所有括号匹配时返回true
}
标签:匹配,递归,int,lo,mi,括号,hi,exp From: https://www.cnblogs.com/abc---/p/17316898.html