题目 1887: 蓝桥杯2017年第八届真题-正则问题

题目

考虑一种简单的正则表达式:
只由 x ( ) | 组成的正则表达式。
小明想求出这个正则表达式能接受的最长字符串的长度。

例如 ((xx|xxx)x|(x|xx))xx 能接受的最长字符串是: xxxxxx,长度是6。

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

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

样例输入

((xx|xxx)x|(x|xx))xx

样例输出

6

解题思路

首先,正则式中实际上有三种符号:

  1. 一是xx,字母直接相连等价于’&',AB等价于A+B,如:xxx为3;
  2. 二是’|',表示或,A|B等价于max(A,B),如:x|xx为2;
  3. 三是’()',表示优先级。

计算机读入字符串,从左到右遍历读取字符,当读取到’(‘时,需要继续读取;当读到’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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值