1. 程式人生 > >2016寒假訓練——字典樹

2016寒假訓練——字典樹

來源:HDU1251

這一題如果用最普通的匹配,那麼,我們需要每一次判斷的時候都進行一次遍歷,這樣不僅時間浪費了,而且太多的時候是重複計算。同時,由於是比較的字首,所以也不可能用KMP來節約時間。我們這裡只能使用字典樹。

直接用模板,道理很簡單的,這裡不細講,關鍵點見註釋。

程式碼(VJ提交):(此程式碼並沒有過,MLE,但是模板是這樣的,網上大部分題解也是這樣寫的,但是這樣是過不了的。。。)

#include<iostream>
#include<cstdio>
#include<cstring>
#include <cstdlib>//用於free
struct Trie
{
    int sum;
    Trie *next[26];//表示後繼的字母。。。
}*root;

void Insert(char *s)
{
    Trie *p,*t;
    int i,n = strlen(s);
    p = root;
    for (i = 0;i < n;i ++)
    {
        if (p->next[s[i]-'a'] == NULL)//如果之前還沒來過
        {
            t = new Trie;
            t->sum = 1;
            for (int j = 0;j < 26;j ++)
                t->next[j] = NULL;
            p->next[s[i]-'a'] = t;
        }
        else p->next[s[i]-'a']->sum ++;//來過的話,節點+1
        p = p->next[s[i]-'a'];
    }
}

int Search(char *s)
{
    Trie *p;
    int i,n = strlen(s);
    p = root;
    for (i = 0;i < n;i ++)
    {
        if (p->next[s[i]-'a'] == NULL)//一旦喲偶一個沒有,直接判定為不是
            return 0;
        p = p->next[s[i]-'a'];
    }
    return p->sum;
}
void Release(Trie *p)//我MLE之後用的,就是用遞迴的方法進行free但是還是無緣無故的MLE,程式碼很好理解
{
    if (p == NULL)
        return ;
    for (int i = 0;i < 26;i ++)
        if (p->next[i] != NULL)
            Release(p->next[i]);
    free(p);
    root = NULL;
    return ;
}
void Init()
{
    root = new Trie;
    root->sum = 0;
    for (int i = 0;i < 26;i ++)
        root->next[i] = NULL;
}
int main ()
{
    char str[15];
    Init();
    while (1)
    {
        gets(str);
        if (strcmp(str,"")==0) break;
        Insert(str);
    }
    while (~scanf ("%s",str))
        printf ("%d\n",Search(str));
    Release(root);
    return 0;
}

我嘗試用STL的map過了,這是AC程式碼:
#include <iostream>
#include <map>
#include <cstring>
#include <string>
using namespace std;

int main()
{
    int i, len;
    char str[10];
    
    map<string, int> m;
    while( gets(str) )
    {
        len = strlen(str);
        if ( !len )
        {
            break;
        }
        for(i = len; i > 0; i--)
        {
            str[i] = '\0';
            m[str]++;
        }
    }
    while( gets(str) )
    {
        cout << m[str] << endl;
    }
    
    return 0;
}
STL參見我的其他文章。。。

相關推薦

2016寒假訓練——字典

來源:HDU1251 這一題如果用最普通的匹配,那麼,我們需要每一次判斷的時候都進行一次遍歷,這樣不僅時間浪費了,而且太多的時候是重複計算。同時,由於是比較的字首,所以也不可能用KMP來節約時間。我們這裡只能使用字典樹。 直接用模板,道理很簡單的,這裡不細講,關鍵點見註釋。

2016寒假訓練——寒假結束

寒假就這樣過去了,二月也就要過去了。 雖然完成了寒假作業,但也只是60+題,而且還有一部分參考了題解和答案。所以,即使量達到了,對於我們的程式碼能力的提高還有很長的一段路要走。 找到一個很好的OJ,hihocoder,雖然題量不大,但是考察方面全面,準備通過這個題庫來準備模

字典3道水題)codeforces 665E&282E&514C

eps trie sub amp ret sea 動態 應該 signed 665E 題意: 給一個數列和一個整數k,求這個數列中異或起來大於等於k的子串數量。 分析: 其實只要維護一個維護前綴和就行了,把前綴和加到字典樹裏,然後遞歸search一下,註意需要剪枝,

hdu1705(字典)

++ pid nbsp cout string char scanf amp pan 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1075 兩個星期沒有刷題了,,從今天開始吧,先從hiho開始刷,鞏固一下之前學的。。 可以用

[ACM] hdu 1251 統計難題 (字典

第一次 stdio.h scrip null 明顯 output 代碼 ane 處理 統計難題 Problem Description Ignatius近期遇到一個難題,老師交給他非常多單詞(僅僅有小寫字母組成,不會有反復的單詞出現),如今老師要他統計出以某

[01字典]求序列完美度(求區間最大異或值)

函數表 字典 style targe efi cnblogs main code blank https://nanti.jisuanke.com/t/15531 解題關鍵:01字典樹模板,用字典樹保存每個數的二進制表示,從而動態維護區間上的最大異或值,註意添加和刪除都可

字典("strcmp()" Anyone? uva11732)

pre call solution only notes take printf when 計算 strcmp() is a library function in C/C++ which compares two strings. It takes two strings

簡述字典

例如 三層 數據 發現 查找 經典題目 nbsp 暴力枚舉 匹配字符串 字典是用來查閱某一個字或詞的,所謂字典樹也就是用於查找某一個數字序列或字符串的。字典樹又稱Trie樹,是一種用樹狀結構存儲字符串的數據結構,經典題目有最長公共前綴、單詞統計等。 字典樹的存儲 字典樹

字典

http 字符串前綴 src 變量 als str trie 指針 roo 字典樹可以用來快速查找字符串前綴 a.b.e.h匯聚於一點,該點為根節點。從根節點開始,每遇到一個紅點就可以組成一個單詞(相當於紅點被標記)。 節點的建立: 1 struct Nod{ 2

hiho兄弟的字典之爭(hiho1014)

應該 http targe 說道 eight 最壞情況 傳說 信息 字母 小Hi和小Ho是一對好朋友,出生在信息化社會的他們對編程產生了莫大的興趣,他們約定好互相幫助,在編程的學習道路上一同前進。 這一天,他們遇到了一本詞典,於是小Hi就向小Ho提出了那個經典的問題:“小H

codechef Xor Queries (可持久化字典)

names truct codec eee one root opened mes main 題目鏈接:codechef Xor Queries 題意: 題解: 一棵可持久化字典樹就行了。 1 #include<bits/stdc++.h> 2 #de

HDU 5687 字典入門

!= 超過 成了 spl 統計 names cnblogs nbsp otto Problem C Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)To

UVA 12333 大數,字典

val long bit pla bre 個數 == one while 題意:給一個數字,看他最小是第幾個菲波那切數列的前綴。 分析: 大數模板就是吊哦。 將菲波那切數列前500個數字放到字典樹上。註意插入的時候不能像普通一樣,只在尾節點處標記,而是一路標記下去。

字典模板

nbsp spa else space iostream ins out ring eat #include<iostream> #include<string> using namespace std; //表示next數組的長度,表示26個

HDU 6059 17多校3 Kanade's trio(字典

要求 tro none sat details num cst void stream Problem Description Give you an array A[1..n],you need to calculate how many tuples (i,j,k)

Hat’s Words(字典的運用)

註意 put ould truct size ++ 需要 sample pan 個人心得:通過這道題,對於樹的運用又加深了一點,字典樹有著他獨特的特點,那個指針的一直轉換著實讓我好生想半天, 不得不佩服這些發明算法人的大腦。 這題的解決方法還是從網上找到的,還好算法是自己實

字典入門

search 字典樹 ins size 簡單 i++ ret 如果 自動機 字典樹 摘自 https://songlee24.github.io/2015/05/09/prefix-tree/ 一、什麽是Trie樹 Trie樹,又叫字典樹、前綴樹(Prefix Tree

Trie字典)(1)

stdio.h public ctu 哈希 pac 索引 cas proc ren   Trie樹。又稱字典樹,單詞查找樹或者前綴樹,是一種用於高速檢索的多叉樹結構。   Trie樹與二叉搜索樹不同,鍵不是直接保存在節點中,而是由節點在樹中的位置決定。

字典的動態與靜態模板

als 字典樹 ins node highlight stream tno log bool 動態鏈表: #include <iostream> #include <cstdio> #include <cstring> #include

poj3376 KMP+字典求回文串數量(n*n)

lis true ring ons words span article memory lac Finding Palindromes Time Limit: 10000MS Memory Limit: 262144K Total Submissions: