NOJ 2111 小明表达式(dfs,模拟)

小明表达式

时间限制(普通/Java) :  1000 MS/ 3000 MS          运行内存限制 : 65536 KByte
总提交 : 29            测试通过 : 5 

比赛描述

TC正在学习编译原理,自创了一套tc expression(小明表达式),(其实是正则表达式的子集)正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。

规则如下:

字母相同是匹配的

'.' 匹配任意的单个字符

'*' 匹配前一个字符0或无限次

匹配必须覆盖整个输入字符串(不是部分)




输入

包含T组数据

每组数据包含两个字符串长度均不超过20,第一个为目标串(仅包含大小写字母),第二个为正则表达式(仅包含大小写字母以及'.','*')


输出

如果匹配,输出true,否则输出false

样例输入

5
aa a
aa aa
aa a*
ab .*
aab c*a*b

样例输出

false
true
true
true
true


题意:中文题不多解释,不过注意第四个 测试样例表明了*可以为.(.*为0个或者多个.),第二个串要与第一个完全一样才可以算匹配(不能多出来字符)

思路:很明显dfs去判断能否匹配,*有点难写,注意细节。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
#define N 25
char a[N],b[N];
int judge(int idb,int len1)
{
    if(b[idb]=='*') idb++;
    for(int i=idb; i<len1; i++)
    {
        if(b[i]!='*'&&i==len1-1) return 0;
        if(b[i]!='*'&&b[i+1]!='*') return 0;
    }
    return 1;
}
int check(int idb,int ida,int len1,int len,int flag)
{
    if(ida==len)
    {
        if(idb==len1||judge(idb,len1))
            return 1;
    }
    if(idb>=len1) return 0;
    if(b[idb]==a[ida])
    {
        if(check(idb+1,ida+1,len1,len,0))
            return 1;
    }
    else if(b[idb]=='.')
    {
        if(check(idb+1,ida+1,len1,len,0))
            return 1;
    }
    else if(idb<len1-1&&b[idb]!=a[idb]&&b[idb+1]=='*')
    {
        if(check(idb+2,ida,len1,len,0))
            return 1;
    }
    else if(b[idb]=='*')
    {
        if(!flag&&check(idb+1,ida-1,len1,len,0))
            return 1;
        if((b[idb-1]=='.'||a[ida]==b[idb-1])&&check(idb+1,ida+1,len1,len,0))
            return 1;
        if((b[idb-1]=='.'||a[ida]==b[idb-1])&&check(idb,ida+1,len1,len,1))
            return 1;
    }
    return 0;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s %s",a,b);
        int flag=0;
        int len=strlen(a),len1=strlen(b);
        if(check(0,0,len1,len,0))  flag=1;
        if(flag) printf("true\n");
        else printf("false\n");
    }
    return 0;
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值