题目
考虑一种简单的正则表达式:
只由 x ( ) | 组成的正则表达式。
小明想求出这个正则表达式能接受的最长字符串的长度。
例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。
输入
一个由x()|组成的正则表达式。输入长度不超过100,保证合法。
输出
这个正则表达式能接受的最长字符串的长度。
样例输入
((xx|xxx)x|(x|xx))xx
样例输出
6
解题思路
首先,正则式中实际上有三种符号:
- 一是xx,字母直接相连等价于’&',
AB
等价于A+B
,如:xxx为3; - 二是’|',表示或,
A|B
等价于max(A,B)
,如:x|xx为2; - 三是’()',表示优先级。
计算机读入字符串,从左到右遍历读取字符,当读取到’(‘时,需要继续读取;当读到’x’时,数目累加一,并继续读取;当读到 ‘|’ 时,x的累加数目截止,并且即为res,继续读取 ‘|’ 之后的字符,直到读到’)‘,计数后与res比较,取两者之间较大的一个,之后再将值返回给读取到’(‘之处。总结一下,即为遇到’(‘进入括号,直到’)‘返回括号内的值;遇到 ‘|’ 比较左右两边的数值,再返回上一级’('。
以上操作层层递进,需要向下求值,也需要向上返回值的思路显然需要用到递归函数和深度优先思想(具体体现在重复的操作,以及遇到最内层括号直接搜索到底 (即遇到’)'才可终止)求值返回上)。因此,基本的思路是先读入,再递归,最后返回值输出。
代码
#include<stdio.h>
#include<string.h>
char a[1001];//输入长度不超过100,保证合法
int lena,k=0;
int max(int a, int b){
return (a>b)?a:b;
}
int DFS(){
int res=0;
while (k<lena){
if (a[k]=='(')
{
k++;
res+=DFS();
k++;/*这个不能加在判断是')'里面,因为|和(的DFS都要靠)来退出循环
如果加在')'里面,则'|'运算后,会因为k指向下一个而无法回到'('
递归调用的时候*/
}
else if (a[k]=='|')
{
k++;
res = max(res,DFS());//或取两者中大的一个
}
else if (a[k]==')')
break;
else //'x'
k++,res++;
}
return res;
}
int main(){
scanf("%s",a);
lena = strlen(a);
printf("%d",DFS());
return 0;
}