首页 > 代码库 > HDU1251 统计难题 【trie树】

HDU1251 统计难题 【trie树】

统计难题

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131070/65535 K (Java/Others)
Total Submission(s): 17302    Accepted Submission(s): 7464


Problem Description
Ignatius近期遇到一个难题,老师交给他非常多单词(仅仅有小写字母组成,不会有反复的单词出现),如今老师要他统计出以某个字符串为前缀的单词数量(单词本身也是自己的前缀).
 

Input
输入数据的第一部分是一张单词表,每行一个单词,单词的长度不超过10,它们代表的是老师交给Ignatius统计的单词,一个空行代表单词表的结束.第二部分是一连串的提问,每行一个提问,每一个提问都是一个字符串.

注意:本题仅仅有一组測试数据,处理到文件结束.
 

Output
对于每一个提问,给出以该字符串为前缀的单词的数量.
 

Sample Input
banana band bee absolute acm ba b band abc
 

Sample Output
2 3 1 0

Trie树入门题,做的时候碰到了不少问题。首先是Ctrl+Z没法结束程序。又一次编译又时好时坏。莫名其妙。CB和DEV都这样。然后就是忘记malloc函数分配的变量单元是随机值。这两点攻克了就好办了。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct Node{
	struct Node *nextAlph[26];
	int num;
} root;

void insert(char *str)
{
	Node *p = &root;	
	int id;
	while(*str){
		id = *str - ‘a‘;
		if(p->nextAlph[id] == NULL){
			p->nextAlph[id] = (Node *)malloc(sizeof(Node));
			p = p->nextAlph[id];
			memset(p->nextAlph, 0, sizeof(p->nextAlph));
			p->num = 0;
		}else  p = p->nextAlph[id];	
		
		++p->num; ++str;
	}	
}

int FIND(char *str)
{
	Node *p = &root;
	int id;
	while(*str){
		id = *str - ‘a‘;
		if(p->nextAlph[id] == NULL) return 0;
		p = p->nextAlph[id];
		++str;
	}
	return p->num;
}

int main()
{
	//freopen("stdin.txt", "r", stdin);
	char str[12];
	while(gets(str), *str) insert(str);	
	while(gets(str) != NULL) printf("%d\n", FIND(str));	
	return 0;
}

粘一个典型的错误代码:用数组错误地模拟trie树,忽略了aaa\nbbb\n\nab这样的情况.

#include <stdio.h>
#include <string.h>

bool alpha[12][26];
int num[12][26];

void insert(char *str)
{
	int id, i;
	for(i = 0; str[i]; ++i){
		id = str[i] - ‘a‘;
		alpha[i][id] = true;
		++num[i][id];
	}
}

int getNum(char *str)
{
	int id, i;
	for(i = 0; str[i]; ++i){
		id = str[i] - ‘a‘;
		if(alpha[i][id] == false) return 0;
	}
	return num[i - 1][id];
}

int main()
{
	//freopen("stdin.txt", "r", stdin);
	char str[12];
	while(gets(str), *str) insert(str);
	while(gets(str)) printf("%d\n", getNum(str));
	return 0;
}

2014.12.16更新

#include <stdio.h>
#include <string.h>

#define maxNode 1000000

char str[12];
struct Trie {
    int ch[maxNode][26];
    int val[maxNode], sz;

    Trie() {
        memset(ch[0], 0, sizeof(ch[0]));
        sz = 1;
    }
    int idx(char ch) { return ch - ‘a‘; }
    void insert(char *str) {
        int u = 0, id, i, len = strlen(str);
        for (i = 0; i < len; ++i) {
            id = idx(str[i]);
            if (!ch[u][id]) {
                memset(ch[sz], 0, sizeof(ch[sz]));
                val[sz] = 0;
                ch[u][id] = sz++;
            }
            u = ch[u][id];
            ++val[u];
        }
    }
    int find(char *str) {
        int u = 0, id, i, len = strlen(str);
        for (i = 0; i < len; ++i) {
            id = idx(str[i]);
            if (ch[u][id]) u = ch[u][id];
            else break;
        }
        return i == len ? val[u] : 0;
    }
} T;

int main() {
    // freopen("stdin.txt", "r", stdin);
    while(gets(str), *str)
        T.insert(str);
    while(gets(str))
        printf("%d\n", T.find(str));
    return 0;
}


HDU1251 统计难题 【trie树】