题目描述:

  在一篇英文文章中查找指定的人名,人名使用二十六个英文字母(可以是大写或小写)、空格以及两个通配符组成(*、?),通配符“*”表示零个或多个任意字母,通配符“?”表示一个任意字母。
如:“J* Smi??” 可以匹配“John Smith” .

请用C语言实现如下函数:
void scan(const char* pszText, const char* pszName);
注:pszText为整个文章字符,pszName为要求匹配的英文名。
请完成些函数实现输出所有匹配的英文名,除了printf外,不能用第三方的库函数等。

下面使用c++实现的。

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cstring>
 6 #include <vector>
 7 #include <string>
 8 #include <climits>
 9 using namespace std;
10 
11 /*
12 从文章的第一个字符开始往后匹配,匹配成功就输出,不成功就
13 继续往后匹配,复杂度O(M*N)
14 dfs
15 可以考虑加上记忆化:bool DP[i][j]表示i到结尾,以及j到结尾,a,b是否匹配
16 */
17 int enda;
18 bool match(string a,int sa,string b,int sb)
19 {
20     //匹配完成
21     if(sb == b.length())
22     {
23         enda = sa;
24         return true;
25     }
26     //未匹配完成
27     if(sa == a.length())
28     {
29         if(b[sb] == '*')
30         {
31             enda = sa;
32             return true;
33         }
34         return false;
35     }
36     if(b[sb] != '*' && b[sb] != '?')
37     {
38         if(a[sa] == b[sb])
39             return match(a,sa+1,b,sb+1);
40         return false;
41     }
42     else
43     {
44         if(b[sb] == '*')
45         {
46             return match(a,sa,b,sb+1)||match(a,sa+1,b,sb);
47         }
48         else
49         {
50             return match(a,sa+1,b,sb+1);
51         }
52     }
53 }
54 
55 void scan(string a,string b)
56 {
57     int sa = 0;
58     int sb = 0;
59 
60     int lena = a.length();
61     int lenb = b.length();
62 
63     while(sa < lena)
64     {
65         if(match(a,sa,b,0))
66         {
67             cout<<a.substr(sa,enda-sa);
68             return;
69         }
70         else
71         {
72             sa++;
73         }
74     }
75     return;
76 }
77 
78 int main()
79 {
80     string a = "J* Smi??";
81     string b = "John Smith";
82     scan(b,a);
83     return 0;
84 }