HDU 3068
关于read函数使用有一些不太能理解的问题出现,在我读完之后选择以一个字符一个字符输出(上限利用read返回值)这种方式得出的结果是和输入一致的,但是直接Printf,可以发现我的字符数组不知道被谁动了,而且恰好是最后一句的重复,倘若结尾多加一个换行符还会有奇怪现象出现。
回到这道题本身,就是简单的利用KMP,KMP写到现在,其实还有一个很重要的细节就是KMP判断时的边界条件,本质上弄清楚边界条件也有益于我们对于KMP算法的理解
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <stack>
#include <cstdio>
#include <cstring>
// #include <unistd.h>
using namespace std;
const int maxl= (1<<16)+5;
const int m= 4;
const char doge[m+2]= "doge";
char a[maxl];
int nxt[maxl];
inline int Equ(char x, char y)
{
return (x & 0x4f) == (y & 0x4f) ? 1 : 0;
}
void PreKmp(const char *ar, int m, int *nx)
{
int i= 0, j= -1;
nx[0]= -1;
while (i< m){
while (j> -1 && !Equ(ar[i], ar[j])){
j= nx[j];
}
++i;
++j;
if (Equ(ar[i], ar[j])){
nx[i]= nx[j];
}
else{
nx[i]= j;
}
}
}
int ReadArt()
{
int cnt= 0;
char *a_b= a;
memset(a, 0, sizeof(a));
cnt= fread(a_b, 1, maxl, stdin);
a[cnt]= '\0';
return cnt;
}
int main(int argc, char const *argv[])
{
int l= ReadArt();
PreKmp(doge, m+1, nxt);
int i= 0, j= 0, ans= 0;
while (i< l){
while (j> -1 && !Equ(a[i], doge[j])){
j= nxt[j];
}
++i;
++j;
if (j>= m){
++ans;
j= 0;
}
}
printf("%d\n", ans);
return 0;
}