句子的语法匹配。这个用DFA确实可以很方便做出来,用递归判断之类的应该也可以。感觉用dfa只需要保证状态转换图对了,基本上就不会出bug了,但是其它的方法去匹配这种类似正则表达式的字符串就容易出错多了。
百度百科的DFA定义如下:
英文全称:Deterministic Finite Automaton, 简写:DFA
DFA定义:一个确定的有穷自动机(DFA)M是一个五元组:M=(K,Σ,f,S,Z)其中
① K是一个有穷集,它的每个元素称为一个状态;
② Σ是一个有穷字母表,它的每个元素称为一个输入符号,所以也称Σ为输入符号字母表;
③ f是转换函数,是K×Σ→K上的映射,即,如 f(ki,a)=kj,(ki∈K,kj∈K)就意味着,
当前状态为ki,输入符为a时,将转换为下一个状态kj,我们把kj称作ki的一个后继状态;
④ S ∈ K是唯一的一个初态;
⑤ Z⊂K是一个终态集,终态也称可接受状态或结束状态。
该题的状态转换图:
![]()
现在再根据状态转换图,写一个模拟转换关系的匹配就非常方便了。。。
代码如下:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 111
 112
 113
 114
 115
 116
 117
 118
 119
 120
 121
 122
 123
 124
 125
 126
 127
 128
 129
 130
 131
 132
 133
 134
 135
 136
 137
 138
 139
 140
 141
 142
 143
 144
 145
 146
 147
 148
 149
 150
 151
 152
 153
 154
 155
 156
 157
 158
 159
 160
 
 | #include <string>#include <vector>
 #include <sstream>
 #include <iostream>
 #include <algorithm>
 using namespace std;
 
 string strNouns[8] =
 {
 "tom", "jerry", "goofy", "mickey",
 "jimmy", "dog", "cat", "mouse"
 };
 
 bool IsNoun(string str)
 {
 for (int i = 0; i < 8; ++i)
 {
 if (str == strNouns[i])
 {
 return true;
 }
 }
 return false;
 }
 
 bool IsVerb(string str)
 {
 return str == "hate" || str == "love"
 || str == "know" || str == "like"
 || str == "hates" || str == "loves"
 || str == "knows" || str == "likes";
 }
 
 bool IsArticle(string str)
 {
 return str == "a" || str == "the";
 }
 
 bool CheckState(vector<string> vs)
 {
 if (vs.empty()) return false;
 
 int nState = 0;
 for (int i = 0; i < vs.size(); ++i)
 {
 
 switch (nState)
 {
 case 0:
 if (IsArticle(vs[i]))
 {
 nState = 1;
 break;
 }
 else if (IsNoun(vs[i]))
 {
 nState = 2;
 break;
 }
 else
 {
 return false;
 }
 
 case 1:
 if (IsNoun(vs[i]))
 {
 nState = 2;
 break;
 }
 else
 {
 return false;
 }
 
 case 2:
 if (vs[i] == "and")
 {
 nState = 0;
 break;
 }
 else if (IsVerb(vs[i]))
 {
 nState = 3;
 break;
 }
 else
 {
 return false;
 }
 
 case 3:
 if (IsArticle(vs[i]))
 {
 nState = 4;
 break;
 }
 else if (IsNoun(vs[i]))
 {
 nState = 5;
 break;
 }
 else
 {
 return false;
 }
 
 case 4:
 if (IsNoun(vs[i]))
 {
 nState = 5;
 break;
 }
 else
 {
 return false;
 }
 
 case 5:
 if (vs[i] == "and")
 {
 nState = 3;
 break;
 }
 else if (vs[i] == ",")
 {
 nState = 0;
 break;
 }
 else
 {
 return false;
 }
 }
 }
 
 return nState == 5;
 }
 
 int main()
 {
 int nT;
 
 scanf("%d%*c", &nT);
 while (nT--)
 {
 vector<string> vs;
 string line, str;
 
 getline(cin, line);
 stringstream ss(line);
 while (ss >> str)
 {
 vs.push_back(str);
 }
 printf("%s\n", CheckState(vs) ? "YES I WILL" : "NO I WON'T");
 }
 
 return 0;
 }
 
 |