in the web for the information of hotels in California ans got piles of choice. Could you help Max pick out those that might be the right hotel?
In the next line there is one integer n(1<=n<=300)representing the number of hotel Max found ,and then n lines follow.Each line contains one string of lowercase character(s),the name of the hotel.
The length of every string doesn't exceed 50.
Solution
給出一個字符串,問下列字符串中與所給匹配的有幾個,?匹配一個字母,*匹配0或多個字母。
一開始想使用暴力掃一遍就好啦,結果*號有些難處理。
模糊匹配的話是可以用簡單dp來做的,f[i][j]代表前i個字符和前j個字符匹配,注意*的話是和後面的所有字符都匹配的
dp的key
f[0][0] = true;//初始化
for (i = 1; i <= ls; ++i)
for (j = 1; j <= lx; ++j)
{
if ((s[i-1] == x[j-1] || s[i-1] == '?') && f[i-1][j-1]) f[i][j] = true;
if (s[i-1] == '*' && f[i-1][j-1])
{
for (k = j-1; k <= lx; ++k) f[i][k] = true;//可以匹配後面的所有,注意匹配0個的時候是j-1
break;
}
}
後來參考他人的思路,可以用遞歸,這樣比較好理解。
#include <cstdio>
#include <cstring>
char s[55], t[55];
int ls, lt;
bool check(int lens, int lent)
{
if (lens == ls && lent == lt) return true;
if (lens == ls || lent == lt) return false;
if (s[lens] == '?' || s[lens] == t[lent]) return check(lens+1, lent+1);
if (s[lens] == '*') for (int i = lent; i <= lt; ++i) if (check(lens+1, i)) return true;//往後看看是不是可以匹配
return false;
}
int main()
{
while (scanf("%s", s) != EOF)
{
ls = strlen(s);
int n, c = 0;
scanf("%d", &n);
while (n--)
{
scanf("%s", t);
lt = strlen(t);
if (check(0, 0)) ++c;
}
printf("%d\n", c);
}
return 0;
}