題目來源洛谷:P1308 統(tǒng)計單詞數(shù)
自動機就是將代碼分為幾種狀態(tài)览绿,而下面這道例題就是一個有窮自動機慌洪,劃分為兩種狀態(tài):
①是空格
②是字母
個人理解有窮自動機就是每一步只做唯一一件事,并且每走一步一定要判斷并修改狀態(tài)顶燕。
代碼如下:
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<cctype>
using namespace std;
const int SPACE = 0;//是空格
const int WORD = 1;//是符合條件的字母
const int OTHER = -1;//是其他字母
char str1[15];
char str2[1000000 + 5];
void strlower(char *a)
{
for (int i = 0; a[i]; i++)
{
if (isupper(a[i]))
a[i] = tolower(a[i]);
}
}
int main()
{
cin.getline(str1, 15);
cin.getline(str2, 1000000 + 5);
strlower(str1);
strlower(str2);
int len = strlen(str1);
int state = SPACE;//初始狀態(tài)為空格狀態(tài),因為下面自動機能夠在空格狀態(tài)全部判斷一遍
int fi = -1;
int sum = 0;
for (int i = 0; str2[i]; i++)
{
switch (state)
{
case SPACE://當(dāng)前面一個字符是空格的狀態(tài)
if (str2[i] == ' ')//如果當(dāng)前字符為空格就繼續(xù)將狀態(tài)置為空格
state = SPACE;
else if (str2[i] == str1[0])//如果當(dāng)前字符和條件第一個字符相等就將狀態(tài)置為符合條件字母
state = WORD;
else//如果當(dāng)前字母都不符合就置其他字母
state = OTHER;
break;
case OTHER://當(dāng)前面一個字符是其他字母的狀態(tài)
if (str2[i] == ' ')//只要判斷當(dāng)前字符是否為空格冈爹,若為空格就置空格
state = SPACE;
break;
default://當(dāng)前面一個字符是符合條件字母的狀態(tài)涌攻,WORD狀態(tài)同時表示所處狀態(tài)和累計字符串長度
if (state < len)
{
if (str2[i] == str1[state])//對應(yīng)相等就將WORD++往后繼續(xù)推
state++;
else if (str2[i] == ' ')
state = SPACE;
else
state = OTHER;
}
else if (state == len)
{
if (str2[i] == ' ')
{
state = SPACE;//記得每一步都要改變狀態(tài)
if (fi == -1)//第一次找到這個字符
fi = i - len;
sum++;
}
else//當(dāng)前字符為其他字符,即條件在其他字母內(nèi)就將狀態(tài)置為其他
state = OTHER;
}
}
}
if (sum == 0)
printf("-1");
else
printf("%d %d", sum, fi);
return 0;
}