题目来源洛谷:P1308 统计单词数
自动机就是将代码分为几种状态,而下面这道例题就是一个有穷自动机,划分为两种状态:
①是空格
②是字母
个人理解有穷自动机就是每一步只做唯一一件事,并且每走一步一定要判断并修改状态。
代码如下:
#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;//初始状态为空格状态,因为下面自动机能够在空格状态全部判断一遍
int fi = -1;
int sum = 0;
for (int i = 0; str2[i]; i++)
{
switch (state)
{
case SPACE://当前面一个字符是空格的状态
if (str2[i] == ' ')//如果当前字符为空格就继续将状态置为空格
state = SPACE;
else if (str2[i] == str1[0])//如果当前字符和条件第一个字符相等就将状态置为符合条件字母
state = WORD;
else//如果当前字母都不符合就置其他字母
state = OTHER;
break;
case OTHER://当前面一个字符是其他字母的状态
if (str2[i] == ' ')//只要判断当前字符是否为空格,若为空格就置空格
state = SPACE;
break;
default://当前面一个字符是符合条件字母的状态,WORD状态同时表示所处状态和累计字符串长度
if (state < len)
{
if (str2[i] == str1[state])//对应相等就将WORD++往后继续推
state++;
else if (str2[i] == ' ')
state = SPACE;
else
state = OTHER;
}
else if (state == len)
{
if (str2[i] == ' ')
{
state = SPACE;//记得每一步都要改变状态
if (fi == -1)//第一次找到这个字符
fi = i - len;
sum++;
}
else//当前字符为其他字符,即条件在其他字母内就将状态置为其他
state = OTHER;
}
}
}
if (sum == 0)
printf("-1");
else
printf("%d %d", sum, fi);
return 0;
}
原文:https://www.cnblogs.com/JMWan233/p/11140838.html