秋季學期一起開心講課-week03-kmp,馬拉車,字典樹
阿新 • • 發佈:2018-11-25
kmp模板:
void findnext(char *str,int *Next,int len) { Next[0] = -1; int i = 0,j = -1; while(i<len) { if(str[i] == str[j]||j==-1) Next[++i] = ++j; else j = Next[j]; } } int kmp(char *s,char *p) { int Next[1000]; int slen = strlen(s); int plen = pstrlen(p); findnext(p,Next,plen); int i = -1,j = -1; while(i<slen) { if(j==-1||s[i]==s[j]) { i++; j++; } else j = Next[j]; if(j == plen) return i - plen; } return -1; }
馬拉車演算法:
int Manacher(char *s) { int len=strlen(s+1); for (int i=1;i<=len;i++) now[2*i-1]='%',now[2*i]=s[i]; now[len=len*2+1]='%'; int pos=0,R=0; for (int i=1;i<=len;i++) { if (i<R) p[i]=min(p[2*pos-i],R-i); else p[i]=1; while (1<=i-p[i]&&i+p[i]<=len&&now[i-p[i]]==now[i+p[i]]) p[i]++; if (i+p[i]>R) { pos=i;R=i+p[i]; } } int MAX=0; for (int i=1;i<=len;i++) MAX=max(MAX,p[i]-1); return MAX; }
字典序:
int trie[400001][26],pos,sum[400001]; void Insert(char *s) { int i = 0,c = 0;///c最初為根節點0 while(s[i]) { int d = s[i] - 'a'; if(!trie[c][d]) //如果為0表示沒編號 trie[c][d] = ++ pos;///編號從1開始 c = trie[c][d]; i ++; } sum[c] ++; } int Query(char *s) { int i = 0,c = 0; while(s[i]) { int d = s[i] - 'a'; if(!trie[c][d]) return 0; c = trie[c][d]; i ++; } return sum[c]; }