【蓝桥杯】历届试题 正则问题(深度优先搜索dfs)

历届试题 正则问题

问题描述
考虑一种简单的正则表达式:
只由 x ( ) | 组成的正则表达式。
小明想求出这个正则表达式能接受的最长字符串的长度。
例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。

输入格式
一个由x()|组成的正则表达式。输入长度不超过100,保证合法。

输出格式
这个正则表达式能接受的最长字符串的长度。

样例输入
((xx|xxx)x|(x|xx))xx

样例输出
6



—— 分割线 ——



分析:
对于题目给出的正则表达式,由于其存在着多重括号,那么对于某个式子而言其就必然需要用到回溯算法来对上一层括号中的内容进行反馈。换言之,本题用搜索算法来进行求解是相当合适的
再看数据范围,输入字符串长度不超过100,这更一步确定了搜索算法的适用性。当然,是深度优先搜索
接下来就以搜索算法的视角对本题进行分析
首先要知道,当程序一遇到”(”时,我们就需要进入一层dfs,这一层dfs的任务是确定在当前这对括号中其所能接受字符串的最大长度。尽管在当前的这对括号中,也许还有多重括号,但是请忽略掉这些,因为我们只需要关心当前dfs的当前搜索任务,更深一层的自然有其对应的dfs以完成。而当我们一遇到”)”(在当前dfs中),就说明已经将当前一对”()”中的结果遍历完毕,接下来直接返回遍历的结果即可
我们注意到在一对”()”中是有可能遇到”|”运算的,这个的处理办法也很简单,我们事先定义两个变量num和ans分别存放当前遍历某个连续”*”串的长度和当前遍历连续”*”串的最大长度,每当一遇到”|”时,我们就比较当前的num和ans,如果num更大就更新ans,否则ans不变,最后令num=0
同样地,在某个dfs结束的时候(即遇到“)”的时候),我们也需要判断ans是否需要更新,规则同上
而统计连续”*”串的长度的任务也就是通过num完成的了,即一遇到”*”就令num++
细心的同学可能已经发现,上面的分析实际上就是一系列的if条件,而其后的行为描述正是if语句中所需要执行的代码。如果仍然对上面的描述不是很清晰的同学,建议直接看代码,如下:



—— 分割线 ——



#include<iostream>
#include<string>
using namespace std;

string str;
int pos,len;

int dfs()
{
	int num=0,ans=0;
	while(pos<len)
	{
		if(str[pos]=='('){
			pos++;
			num+=dfs();
		}
		else if(str[pos]==')'){
			pos++;
			break;
		}
		else if(str[pos]=='|'){
			pos++;
			ans=max(num,ans);
			num=0;
		}
		else{
			num++;
			pos++;
		}
	}
	ans=max(num,ans);
	return ans;
}
 
int main()
{
	cin>>str;
	pos=0,len=str.length();
	cout<<dfs()<<endl;
	return 0;
}
发布了50 篇原创文章 · 获赞 101 · 访问量 1万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 书香水墨 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览