字符串算法总结

集训刚开始几天学了一下字符串算法(只看了一点点), 不过今天开始要看一些数学计算几何方面的东西, 所以先写个总结, 以后回来继续看.

暂时给出kmp以及一些练习题, AC自动机和hash后续给出

主要介绍:
0. Trie树
1. kmp算法
2. AC自动机 (待填坑)
3. 字符串哈希 (待填坑)

Trie树

又叫字典树, 其实这个数据结构还是比较直观的, 比如所有字符串都是26个字母的, 那么这个字典树就是一个26叉树, 如果abcd存在, 那么字典树里就有root -> a -> b -> c -> d的一条路.
请允许我盗图..

#include <cstdio>
#include <cstring>
using namespace std;
const int segma_size = 26;
const int maxsize = 50000;
struct TrieNode{
    int val;
    int cnt;
    int next[segma_size];
    TrieNode(){
        memset(next, 0, sizeof(next));
        cnt=0;
    }
};
TrieNode trie[maxsize];
int tcnt;
void init()
{
    tcnt = 1;
}
void insert(char *key)
{
    char *p = key;
    int u = 0;
    while(*p)
    {
        if(trie[u].next[*p-'a'] == 0)
            trie[u].next[*p-'a'] = tcnt++;
        u = trie[u].next[*p-'a'];
        p++;
    }
    trie[u].cnt = 1;
}
int find(char *key)
{
    char *p = key;
    int u = 0;
    while(*p)
    {
        if(trie[u].next[*p-'a'] == 0)
            return 0;
        u = trie[u].next[*p-'a'];
        p++;
    }
    return trie[u].cnt;
}

这是我写的一个静态的Trie树, 不要用new, delete来做..太慢

kmp算法

kmp算法是用于处理两个字符串匹配的算法, 有一个较长的文本串S(长度n), 模式串P(长度m), 在S中查找P是否出现过, 暴力算法为O(n*m).

KMP算法是一个比较晦涩的算法, 但是可以做到O(n+m)的复杂度

大意是计算出模式串的Next数组.在暴力匹配的时候, i指针在文本串上向后滑动, j指针在模式串上向后滑动, 如果匹配失败, 则i回滚到模式串的开头后一个位置继续开始匹配, 即 每次与模式串匹配失败, i向前回滚, 因此最坏情况下, 每次都回滚m个位子, 总共n次, 复杂度为O(m*n)

而求出Next数组后, i指针不前移, 利用Next数组将模式串跳转,

例如模式串是abcdabce, 匹配abcdabc都成功, 然而匹配e的时候发现, 跟文本串(例如abcdabcfabc)的f不一样, 此时, abcdabce中, e前面的abc和文本串f前面的abc相同, 而e前面的abc和模式串开头的abc也相同, 那么只需要从d开始与文本串匹配即可. (前面已经一样, 不用比较了)

给一个非常详细的帖子, 从头到尾理解KMP
或者可以看看hihocoder里的KMP算法那个, 也不错

这里也有一个帖是介绍了比较多的好的题目的KMP练习题

求Next数组的一个模板, kmp匹配就不写了, 并不是所有时候都需要匹配..Next数组灵活使用比较蛋疼..

#include <cstdio>
#include <cstring>
using namespace std;
const int maxsize = 200050;
int _next[maxsize];
void getNext(char *p)
{
    int pLen = strlen(p);
    int i, k;
    _next[0] = -1;
    for(i=1; i<=pLen; i++)
    {
        k = _next[i-1];
        while(k>=0 && p[k] != p[i-1])
            k = _next[k];
        _next[i] = k+1;
    }
}

AC自动机

坑待填.

字符串hash

坑待填

最近做的一些题.

HDU3336
HDU2594
HDU2087

POJ1961
POJ2406
POJ2752
POJ3461

POJ2513
POJ2503
POJ3630
POJ2001
POJ1056

先做别的了.. 这些题代码回头给链接

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值