soj 1197. Hotel

题意:

给一个记忆中的字符串s,由'a'-'z','*','?'组成,'*'表示忘了一串字符(可以是0个字符),'?'表示忘了一个字符。

比如*可以表示任意字符串;?ab可以表示aab,bab等,但是不能表示aaab。

再给出N个实际的字符串t,由'a'-'z'组成,问这N个字符串有多少满足记忆中的字符串的形式。

思路:

将每一个t与s进行对比,记布尔值f[i][j]表示s[1...i]与t[1...j]相符与否,然后递推,最后s与t是否相符就是f[lens][lent]。

递推方程:

1)如果s[i] == t[j] 或者s[i] == '?',那么f[i][j] = f[i-1][j-1]

2)如果s[i] == '*',那么f[i][j] = f[i][j-1] || f[i-1][j-1] || f[i-1][j]

其中注意:1)初始化f[0][0] = true;2)当s[i] == '*' 的时候f[i][0] = f[i-1][0]要单独考虑进去。

code:

#include <cstdio>
#include <cstring>
#define N 55
int n, ans;
char tar[N], hot[N];
bool f[N][N];
bool match()
{
	int tlen=strlen(tar+1), hlen=strlen(hot+1);
	memset(f, false, sizeof(f));
	f[0][0] = true;
	for (int i = 1; i <= tlen; ++ i)
	{
		if (tar[i] == '*') f[i][0] = f[i-1][0];
		for (int j = 1; j <= hlen; ++ j)
		{
			if (tar[i]==hot[j] || tar[i]=='?') f[i][j] = f[i-1][j-1];
			else if (tar[i]=='*') f[i][j] = f[i][j-1] || f[i-1][j-1] || f[i-1][j];
		}
	}
	return f[tlen][hlen];
}
int main()
{
	while (~scanf("%s", tar+1))
	{
		ans = 0;
		scanf("%d", &n);
		while (n --)
		{
			scanf("%s", hot+1);
			if (match()) ans ++;
		}
		printf("%d\n", ans);
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值