Description
小沐几年前到德国去旅游时住过一间旅店,觉得它非常有特色,这次旅游打算还要住那里。但是他已经记不清旅店的名字了,于是他使用通配符"*"和"?"和26个小写字母来描述。注意,这里的"*"代表0个或任意多个字母,"?"代表一个字母。
小沐在网上找到了一系列旅店的名字,他想知道有多少间旅店能与他的描述相匹配。
Input
包含多组数据。每组数据的第一行为一个字符串,表示小沐印象中的旅店名字描述;接下来一行为一个整数n,表示在网上找到的一些旅店名字数量;再接下来的n行,每行一个字符串,表示网上提供的旅店名字。
Output
针对每组数据,输出一个整数,表示与小沐印象中的旅店名字相匹配的网上的旅店名字的数量。
Sample Input 1
herbert 2 amazon herbert ?ert* 2 amazon herbert * 2 amazon anything herbert? 2 amazon herber
Sample Output 1
1 0 2 0
Hint
n<=10000 , 每个字符只由'*'和'?'和26个小写字母组成,串长度不超过50。
a[]表示印象中的描述
b[]表示搜到的旅馆
d[i][j]表示a的前i个和b的前j个能不能匹配
方程见代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = 55;
char a[maxn], b[maxn];
int n, m;
bool d[maxn][maxn];
bool solve(){
memset(d, 0, sizeof(d));
m = strlen(b+1);
d[0][0] = true;
for(int i=1;i<=n;i++){
if(a[i] == '*') d[i][0] = d[i-1][0];
for(int j=1;j<=m;j++){
bool t = false;
if(a[i] == b[j] || a[i] == '?') t = t || d[i-1][j-1];
if(a[i] == '*') t = t || d[i-1][j] || d[i][j-1];
d[i][j] = t;
}
}
return d[n][m];
}
int main(){
int q, ans;
while(scanf("%s", a+1) == 1){
n = strlen(a+1);
scanf("%d", &q);
ans = 0;
while(q--){
scanf("%s", b+1);
if(solve()) ans++;
}
printf("%d\n", ans);
}
return 0;
}