HDU 1251 statistical puzzle (dictionary tree)

1, Title Description

Statistical puzzles

Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 73692 Accepted Submission(s): 25355(2020/2/14 17:31)

Problem Description

Ignatius recently encountered a problem. The teacher gave him many words (only lowercase letters, no repeated words). Now the teacher asked him to count the number of words prefixed with a string (the word itself is also its own prefix)

Input

The first part of the input data is a word list, one word in each line, the length of the word is no more than 10, they represent the words given by the teacher to Ignatius for statistics, and a blank line represents the end of the word list. The second part is a series of questions, one question in each line, and each question is a string

Note: this question only has a set of test data, processing to the end of the file

Output

For each question, give the number of words prefixed with the string

Sample Input

banana
band
bee
absolute
acm

ba
b
band
abc

Sample Output

2
3
1
0

Author

Ignatius.L

2, Description of algorithm analysis

Close to template questions. Add the item size to the node information of the dictionary tree. Every time a word is added, the size of each position passing by is + 1. When you need to get the number of words with a prefix, you only need to return the size member of the corresponding node of the last digit of the prefix in the dictionary tree.

3, AC code

Version 1: (218 ms)

#include<cstdio>
#include<map>
#pragma warning(disable:4996)
class trie {
private:
    struct node { std::map<char, node*> next; bool end = false; unsigned size = 0; };
    node* root;
    std::map<char, node*>::iterator I; std::pair<char, node*> P;
public:
    trie() { root = new node(); }
    void insert(const char* const k) {
        node* p = root; const char* q = k;
        while (*q != 0) {
            I = p->next.find(*q);
            if (I == p->next.end()) {
                P.first = *q; P.second = new(node)(); p->next.emplace(P); I = p->next.find(*q);
            }
            ++p->size; p = I->second, ++q;
        }
        p->end = true; ++p->size;
    }
    unsigned find(const char* const w) {
        node* p = root; const char* q = w;
        while (*q != 0) {
            I = p->next.find(*q);
            if (I == p->next.end()) { return false; }
            p = I->second, ++q;
        }
        return p->size;
    }
};
trie t; char w[32];
int main() {
    for (;;) {
        gets_s(w); if (w[0] == 0)break;
        t.insert(w);
    }
    for (;;) {
        gets_s(w); if (feof(stdin))return 0;
        printf("%u\n", t.find(w));
    }
}

Version 2: (171 ms)

#include<cstdio>
#include<algorithm>
#pragma warning(disable:4996)
class trie {
private:
    struct node {
        node* next[26]; bool end; unsigned size;
        node() { end = false; size = 0; std::fill(next, next + 26, nullptr); }
    };
    node* root;
    char id(const char& x) { return x - 'a'; }
public:
    trie() { root = new node(); }
    void insert(const char* const k) {
        node* p = root; const char* q = k;
        while (*q != 0) {
            if (p->next[id(*q)] == nullptr) { p->next[id(*q)] = new(node)(); }
            ++p->size; p = p->next[id(*q)], ++q;
        }
        p->end = true; ++p->size;
    }
    unsigned find(const char* const w) {
        node* p = root; const char* q = w;
        while (*q != 0) {
            if (p->next[id(*q)] == nullptr) { return 0; }
            p = p->next[id(*q)], ++q;
        }
        return p->size;
    }
};
trie t; char w[32];
int main() {
    for (;;) {
        gets_s(w); if (w[0] == 0)break;
        t.insert(w);
    }
    for (;;) {
        gets_s(w); if (feof(stdin))return 0;
        printf("%u\n", t.find(w));
    }
}
221 original articles published, 20 praised, 10000 visitors+
Private letter follow

Tags: Java

Posted on Fri, 14 Feb 2020 06:14:08 -0500 by d_barszczak