字典树vskmp

本篇博客旨在巩固基础代码学习,不足之处还望广大大牛批评指出不胜感激

一字典树

字典树目的在于可以节省大量空间存储单词或其他字符串,并且可以快速查找。

poj3630

题意:

给出若干字符串,判断某个字符串是否是其他字符串的前缀,有这样的字符串输出“NO”,否则输出“YES”。

思路:

根据字符串输的顺序不同需要考虑第一种:该字符串是否是上面输入过的字符串的前缀

                                                   第二种:该字符串是否包含之前输入的某个字符串

注意:

根据题目给定的范围可以算出字典树节点数最多有10*10000=100000,节点数少的话会wrongRE;

输入字符串之前要getchar(),以防输入n后的回车被读入,否则会RE;

C++代码如下(数组实现字典树插入,此题还未涉及字典树查找)

#include
#include
#include
#include
#include
using namespace std;
int tot;
int s[100010][10];
int iwn[100010];
int insertt(char *a,int rt)
{
    int l=strlen(a);
    for(int i=0; i

二 KMP算法

KMP算法是为了解决字符串快速匹配需求的算法,其中next数组起了举足轻重的作用,具体实现建议参看小甲鱼的一个视频非常详尽,这里涉及到了一个字符串的前缀和后缀的概念(本人也是历时n个小时才参透了其中的一二,甚是惭愧,写下这篇博客纪念一下)
c++模板:
#include
#include
#include
#include
using namespace std;
string s,t;
int next[100000];
int tlen=0;
int slen=0;
void getnext()
{
    int i,j;
    i=-1;
    j=0;
    next[0]=-1;
    while(j>s>>t)
    {
        memset(next,0,sizeof(next));
        getnext();
        tlen=t.size();
        slen=s.size();
        int u=indexfind_();
        if(u==-1)printf("NO:没有匹配\n");
        else
            printf("YES:第一次匹配的位置为:%d\n",u);
        printf("匹配的次数: %d\n",count_kmp());
    }
}
一道例题体会next数组神奇的应用
poj2752

题目大意:
Example: Father='ala', Mother='la', we have S = 'ala'+'la' = 'alala'. Potential prefix-suffix strings of S are {'a', 'ala', 'alala'}. Given the string S, could you help the little cat to write a program to calculate the length of possible prefix-suffix strings of S? (He might thank you by giving your baby a name:) 
给定字符串T,求出T的所有可能相同前后缀的长度。如: "alala"的前缀分别为{"a", "al", "ala", "alal", "alala"}, 后缀分别为{"a", "la", "ala", "lala", "alala"}. 其中有{"a", "ala", "alala"}是相同的,即输出1 3 5.

下图很清晰的表达出了思路,(借鉴了一个大牛的神图)
    

如上图,黑色线来代表字符串t,其长度是l,红色线的长度代表next[l],由next数组定义得next[l]前的字符串前缀和next[l]前的字符串的后缀及其所有子串完全相同(也就是两条线所对应的位置)。我们再求出next[l]位置处的next值,也就是图中蓝线对应的长度。同样可以得到两个蓝线对应的子串肯定完全相同,又由于第二段蓝线属于左侧红线的后缀,所以又能得到它肯定也是整个字符串的后缀。因此这道题,就是求出 l 处的next值,并一步一步的向下(递归)求出所有的next值直到next值等于零,然后倒序输出得到答案。

c++代码如下:

#include
#include
#include
#include
using namespace std;
string t;
int next[500000];
int tlen;
void getnext()
{
    int i,j;
    i=-1;
    j=0;
    next[0]=-1;
    while(j>t)
    {
        memset(next,0,sizeof(next));
        getnext();
        tlen=t.size();
        int k=0,ans[500000]={0};
        int j=t.size();
        while(j!=0)
        {
           ans[k++]=next[j];
           j=next[j];
        }
       for(int i=k-2;i>=0;i--)
        printf("%d ",ans[i]);
       printf("%d\n",tlen);
    }
}


 

你可能感兴趣的:(算法,字符串,字典树)