hdu1251 (字典树裸题,求前缀数量)

原题地址;http://acm.hdu.edu.cn/showproblem.php?pid=1251
题意:给出一些字符串,然后再给出询问的前缀,判断在之前的字符串中,询问的前缀有多少是前面字符串的前缀

思路:没什么好说的,就是一个用来测试字典树模板的
指针版本代码:

/*判断前缀的数量 */
#include 
#include 
#include 
using namespace std;
struct trie {
    int num;//前缀数量
    trie *next[26];//这道题范围是小写字母,所以开到26即可
    trie() {
        memset(next, 0, sizeof(next));//记得初始化
        num = 0;
    }
} root;//这是根节点,字典树的根节点不存储任何信息
void Insert(char  *s) {
    trie *p = &root;//从根节点开始遍历
    for(int i = 0; s[i]; i++) {
        if(p->next[s[i] - 'a'] == NULL) p->next[s[i] - 'a'] = new trie;//如果不存在当前字符,就创建
        p = p->next[s[i] - 'a'];
        p->num++;
    }
}
int Find(char *s) {
    trie *p = &root;
    for(int i = 0; s[i]; i++) {
        if(p->next[s[i] - 'a'] == NULL) return 0;
        p = p->next[s[i] - 'a'];
    }
    return p->num;
}
char a[15];
int main() {
    while(gets(a) && a[0] != 0) {
        Insert(a);
    }
    while(gets(a) && a[0] != 0) {
        printf("%d\n",Find(a));
    }
    return 0;
}

数组版本代码:

#include  
#include  
#include  
#include   
#include  
using namespace std;
const int  maxn = 1e6 + 5;
char a[15];
int pos = 1; //节点标号
int trie[maxn][26];
int num[maxn];
void Insert(char *s) {
    int root = 0;
    for(int i = 0; s[i]; i++) {
        if(trie[root][s[i] - 'a'] == 0) {
            trie[root][s[i] - 'a'] = pos++;
        }
        root = trie[root][s[i] - 'a'];
        num[root]++;
    }
}
int Find(char *s) {
    int root = 0;
    for(int i = 0; s[i]; i++) {
        if(trie[root][s[i] - 'a'] == 0) return 0;
        root = trie[root][s[i] - 'a'];
    }
    return num[root];
}

int main() {
    while(gets(a) && a[0] != 0) {
        Insert(a);
    }
    while(gets(a) && a[0] != 0) {
        printf("%d\n", Find(a));
    }
    return 0;
}

你可能感兴趣的:(ACM_字典树)