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 ", ans); } return 0; }