hdu 3065 刚A了道题,很艰难,贴下代码。。

病毒侵袭持续中

http://acm.hdu.edu.cn/showproblem.php?pid=3065

Accepted

3065

375MS

8732K

3043B

C++

// 今天好不容易把自动机学会了,AC了一道题,不过我自己写的代码还有看不懂的,请大牛指教。。。。

#include <cstdlib>

#include <cstdio>

#include <cstring>

#include <cassert>

#include <queue>

#include <cctype> // 用于 isupper 判断是否为大写字母

#include <iostream>

#include <string>

using namespace std;

 

class TrieTree {

private:

    static const int MAXELEM = 26;

    TrieTree *next[MAXELEM];

    TrieTree *fail;

    int id;

 

public:

 

    TrieTree() : id(-1), fail(NULL) {

        memset(next, 0, sizeof (next));

    }

 

    int &operator[](string s) {

        TrieTree *p = this;

        for (int h = 0; h < s.length(); ++h) {

            assert(isupper(s[h])); // 断言 *s 是一个大写字母 ,如果断言失败,程序终止 退出值 3

            int i = s[h] - 'A';

            if (p->next[i] == NULL) p->next[i] = new TrieTree;

            p = p->next[i];

        }

        return p->id;

    }

 

    void build() {

        queue<TrieTree*> q;

        this->fail = NULL;

        for (int i = 0; i < MAXELEM; ++i) {

            if (next[i] == NULL)continue;

            next[i]->fail = this;

            q.push(next[i]);

        }

        while (!q.empty()) {

            TrieTree * p = q.front();

            q.pop();

            for (int i = 0; i < MAXELEM; ++i) {

                if (p->next[i] == NULL)continue;

                q.push(p->next[i]);

                TrieTree *tmp = p->fail;

                while (tmp && tmp->next[i] == NULL)

                    tmp = tmp->fail;

                if (tmp) p->next[i]->fail = tmp->next[i];

                else p->next[i]->fail = this;

            }

        }

    }

 

    void match(string text, int *hash) { //匹配 ,将对应 id 存到hash数组中

        TrieTree *p = this;

        for (int h = 0; h < text.length(); ++h) {

            if (!isupper(text[h])) {

                p = this;

                continue;

            }

            int i = text[h] - 'A';

            while (p && p->next[i] == NULL)

                p = p->fail;

            if (p)p = p->next[i];

            else p = this;

            for (TrieTree *tmp = p; tmp != this; tmp = tmp->fail) {

                if (tmp->id != -1)++hash[tmp->id];

            }

        }

    }

 

    ~TrieTree() { //回收内存,不回收好像也能过,数据有点弱

        for (int i = 0; i < MAXELEM; ++i) {

            if (next[i]) delete next[i];

        }

    }

};

 

int main(int argc, char** argv) {

    int n;

    while (cin >> n) {

        string *in = new string[n];

        TrieTree tree;

        for (int i = 0; i < n; ++i) {

            cin >> in[i];

            tree[in[i]] = i;

        }

        tree.build();

        string text;

        cin >> text;

        int *hash = new int[n];

        memset(hash, 0, sizeof (int) *n);

        tree.match(text, hash);

        for (int i = 0; i < n; ++i) {

            if (hash[i] != 0) cout << in[i] << ": " << hash[i] << endl;

        }

        delete []in;

        delete []hash;

    }

    return EXIT_SUCCESS;

}

posted on 2011-08-22 11:02  成诺  阅读(489)  评论(1编辑  收藏  举报

导航