问题描述
题目链接:正则问题
资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
考虑一种简单的正则表达式:
只由 x ( ) | 组成的正则表达式。
小明想求出这个正则表达式能接受的最长字符串的长度。
例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。
输入格式
一个由x()|组成的正则表达式。输入长度不超过100,保证合法。
输出格式
这个正则表达式能接受的最长字符串的长度。
样例输入
((xx|xxx)x|(x|xx))xx
样例输出
6
思路分析
思路参考:【蓝桥杯】历届试题 正则问题
强烈推荐这个博主!!!
它写的蓝桥杯题目思路非常清晰!!!
对于题目给出的正则表达式,由于其存在着多重括号,那么对于某个式子而言其就必然需要用到回溯算法来对上一层括号中的内容进行反馈。换言之,本题用搜索算法来进行求解是相当合适的
再看数据范围,输入字符串长度不超过100,这更一步确定了搜索算法的适用性。当然,是深度优先搜索 接下来就以搜索算法的视角对本题进行分析
(1)首先要知道,当程序一遇到”(”时,我们就需要进入一层dfs,这一层dfs的任务是确定在当前这对括号中其所能接受字符串的最大长度。尽管在当前的这对括号中,也许还有多重括号,但是请忽略掉这些,因为我们只需要关心当前dfs的当前搜索任务,更深一层的自然有其对应的dfs以完成。而当我们一遇到”)”(在当前dfs中),就说明已经将当前一对”()”中的结果遍历完毕,接下来直接返回遍历的结果即可;
(2)我们注意到在一对”()”中是有可能遇到”|”运算的,这个的处理办法也很简单,我们事先定义两个变量cnt和max分别存放当前遍历某个连续””串的长度和当前遍历连续””串的最大长度,每当一遇到”|”时,我们就比较当前的cnt和ans,如果cnt更大就更新max,否则,max不变,最后令cnt=0;
(3)同样地,在某个dfs结束的时候(即遇到“)”的时候),我们也需要判断max是否需要更新,规则同上;
(4)而统计连续”x”串的长度的任务也就是通过cnt完成的了,即一遇到”*”就令cnt++。
代码实现
#include<stdio.h>
int dfs(){
char ch;
int max=0,cnt=0;// max用来保存当前遍历连续串的最大长度,cnt用来表示当前遍历连续串的长度
while(1){
ch=getchar();// 每次循环读取一个字符
if(ch=='(') cnt+=dfs();// 遇到(就递归
else if(ch=='x') cnt++;//遇到字符,cnt就加1
else if(ch=='|')
{// 遇到|就保存|之前最大的长度并且将cnt清0
max=(max>cnt)?max:cnt;
cnt=0;
}
else
{// 遇到)就返回最大,最后一个字符为\n就是递归的出口
max=(max>cnt)?max:cnt;
return max;
}
}
}
int main(){
printf("%d",dfs());
return 0;
}
参考:C语言实现 正则问题