1. 程式人生 > >HDU1251 統計難題 【trie樹】

HDU1251 統計難題 【trie樹】

courier ava 自己的 while onos ets ctrl pan alloc

統計難題

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樹】