首页 > 其他分享 >如何用递归实现简单的单括号匹配

如何用递归实现简单的单括号匹配

时间:2023-04-13 23:14:03浏览次数:32  
标签:匹配 递归 int lo mi 括号 hi exp

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

相关文章

  • 【LBLD】滑动窗口算法延伸:RABIN KARP 字符匹配算法
    滑动窗口算法延伸:RABINKARP字符匹配算法187.重复的DNA序列普通方法:classSolution{public:vector<string>findRepeatedDnaSequences(strings){intn=s.size();unordered_set<string>seen;unordered_set<string>res;......
  • 求n的阶乘(递归调用)
    求n的阶乘。#include<iostream>usingnamespacestd;unsignedfac(unsignedm){ unsignedn; if(m==0) n=1; else n=fac(m-1)*m; returnn;}intmain(){ unsignedx,y; cin>>x; y=fac(x); cout<<y; return0;}......
  • C # 9.0 的模式匹配
    voidM(objecto1,objecto2){vart=(o1,o2);if(tis(int,string)){}//testifo1isanintando2isastringswitch(o1){caseint:break;//testifo1isanintcaseSystem.String:break;//testifo1isastring}}关系模式 与常数值相......
  • oracle递归查询法
    select*from表名startwith查询的条件connectbyprior等值条件(一个表中两个值相等的字段)查询的结果集:满足连接的值=查询条件,startwith子句:遍历起始条件,有个小技巧,如果要查父结点,这里可以用子结点的列,反之亦然。connectby子句:连接条件。......
  • [转载]php递归生成树形结构(几种常见的数据结构)
    版权声明:本文为CSDN博主「陈文焕」的原创文章,遵循CC4.0BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/qq_23116221/article/details/109910846pid找上级id$array=array(array('id'=>1,'pid'=>0,'n'=>'河北省'),ar......
  • OpenCv单模版多目标匹配
    OpenCv单模版多目标匹配单模版匹配出现的问题一、关于单模版匹配,我一开始用的是光线较暗的图,结果根据模版匹配到的位置并不正确。我后来想用阈值把图形的特征提取出来,在把模版的特征和原图的特征进行比较,如下:importcv2img=cv2.imread('/Users/duanhao/Desktop/photo/liuk......
  • JS 根据key查找对象数组中符合的一项 返回对象(递归)
    在一个复杂的数组对象数据中(嵌套多层),通过key值返回对应的对象1方法:parseJson(jsonObj,key,value){//循环所有键letarray=[]for(letvinjsonObj){letelement=jsonObj[v]//1.判断是对象或者数组if(typeof(ele......
  • 正则对税号的匹配逻辑
    税号一般由15或18位数字组成,其中:-15位税号:前6位是所属地区(通常是行政区划代码前6位)、中间6位是组织机构代码、最后3位是登记管理部门代码。-18位税号:前2位是登记管理部门代码、中间6位是组织机构代码、最后10位是由国家税务总局统一分配的顺序编码。所以,对于税号的正则匹配逻......
  • UVa 112 Tree Summing (scanf()去空格&递归&二叉树遍历)
    112-TreeSummingTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=48BackgroundLISPwasoneoftheearliesthigh-levelprogramminglanguagesand,withFORTRAN,isoneoft......
  • UVa 489 Hangman Judge (模拟&字符串匹配)
    489-HangmanJudgeTimelimit:3.000secondshttp://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=show_problem&problem=430In``HangmanJudge,''youaretowriteaprogramthatjudgesaseriesofH......