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;
}
posted @ 2021-03-30 15:13  IdiotNe  阅读(35)  评论(0编辑  收藏  举报