24h購物| | PChome| 登入
2011-07-11 08:20:23| 人氣910| 回應0 | 上一篇 | 下一篇

Trie (單詞查找樹)

推薦 0 收藏 0 轉貼0 訂閱站台

做了三種版本, 優化只是在輸出的方面優化而已, 請多多見諒
第一次非遞迴的東西

[非遞迴版+優化]


/**********************************************************************************/
/*  Problem: a177 "逆逆向思考" from Trie                                     */
/*  Language: C                                                                   */
/*  Result: AC (648ms, 6352KB) on ZeroJudge                                       */
/*  Author: morris1028 at 2011-07-11 00:13:50                                     */
/**********************************************************************************/


#include<stdio.h>
#include<stdlib.h>
typedef struct TrieNode    {
    char c;
    struct TrieNode *kid, *peer;
}TrieNode;
typedef struct Trie    {
    struct TrieNode *root;
}Trie;
typedef struct Stack {
    struct Stack *prev;
    struct TrieNode *now, *curr;    
    int dv;
    char work;
}Stack;

void Trieinit(Trie*);
void InsTrie(Trie*, char s[]);
void TriePrint(TrieNode*, int);

void Trieinit(Trie *tree) {
    tree->root = (TrieNode*)malloc(sizeof(TrieNode));
    tree->root->c = ' ';
    tree->root->kid = tree->root->peer = NULL;
}

void TriePrint(TrieNode *now, int dv) {
    Stack *stack, *temp;
    stack = (Stack*)malloc(sizeof(Stack));
    stack->prev = NULL, stack->now = now, stack->dv = dv, stack->work = 0;
    int a, Atop = 0;
    char Ans[30005], flag, flag2;
    while(stack != NULL) {
        if(stack->work == 0) {            
            if(flag == 1) {
                for(a = 0, flag = 0; a < stack->dv; a++)
                    Ans[Atop++] = ' ', Ans[Atop++] = ' ', Ans[Atop++] = ' ';
            }
            stack->curr = stack->now->kid, stack->work = 1;
            Ans[Atop++] = '[', Ans[Atop++] = stack->now->c, Ans[Atop++] = ']';

        }            
        flag2 = 0;
        while(stack->curr != NULL) {
            temp = (Stack*)malloc(sizeof(Stack));
            temp->now = stack->curr, temp->prev = stack, temp->dv = stack->dv+1;
            temp->work = 0;
            stack->curr = stack->curr->peer;
            stack = temp, flag2 = 1;
            break;
        }
        if(flag2) continue;
        if(stack->now->kid == NULL)    Ans[Atop] = '\0', puts(Ans), flag = 1, Atop = 0;
        temp = stack->prev, free(stack->now), free(stack), stack = temp;
    }
}
void InsTrie(Trie *tree, char s[]) {
    TrieNode *curr = tree->root, *prev = NULL, *temp, *p;
    int a;
    for(a = 0; s[a]; a++) {
        p = curr, curr = p->kid, prev = NULL;
        while(curr != NULL && curr->c < s[a]) {
            if(curr->c < s[a])    prev = curr, curr = curr->peer;
        }
        
        if(curr == NULL) {
            temp = (TrieNode*)malloc(sizeof(TrieNode));
            temp->c = s[a], temp->kid = temp->peer = NULL;
            if(prev == NULL)    p->kid = temp;
            else    prev->peer = temp;
            curr = temp;
        }
        else {
            if(curr->c == s[a])    {continue;}
            temp = (TrieNode*)malloc(sizeof(TrieNode));
            temp->c = s[a], temp->kid = NULL;
            if(curr == p->kid)    p->kid = temp, temp->peer = curr;
            else    prev->peer = temp,    temp->peer = curr;
            curr = temp;
        }
    }
}

main() {
    int N;
    char s[10001];
    while(scanf("%d", &N) == 1) {
        Trie Tree;
        Trieinit(&Tree);
        getchar();
        while(N--)
            gets(s), InsTrie(&Tree, s);
        TriePrint(Tree.root, 0);
    }
    return 0;
}


[遞迴版 + 優化]

/**********************************************************************************/
/*  Problem: a177 "逆逆向思考" from Trie                                     */
/*  Language: C                                                                   */
/*  Result: AC (624ms, 6660KB) on ZeroJudge                                       */
/*  Author: morris1028 at 2011-07-10 22:04:56                                     */
/**********************************************************************************/


#include<stdio.h>
#include<stdlib.h>
typedef struct TrieNode    {
    char c;
    struct TrieNode *kid, *peer;
}TrieNode;
typedef struct Trie    {
    struct TrieNode *root;
}Trie;

void Trieinit(Trie*);
void TrieFree(TrieNode*);
void InsTrie(Trie*, char s[]);
void TriePrint(TrieNode*, int);

void Trieinit(Trie *tree) {
    tree->root = (TrieNode*)malloc(sizeof(TrieNode));
    tree->root->c = ' ';
    tree->root->kid = tree->root->peer = NULL;
}
void TrieFree(TrieNode *now) {
    if(now == NULL)    return;
    TrieNode *curr = now->kid, *prev;
    while(curr != NULL) {
        prev = curr, curr = curr->peer;
        TrieFree(prev);
    }
    free(now);
}
int flag, Atop = 0;
char Ans[30001];
void TriePrint(TrieNode *now, int dv) {
    if(now == NULL)    return;
    TrieNode *curr = now->kid;
    if(flag == 1) {
        int a;
        for(a = 0, flag = 0; a < dv; a++)
            Ans[Atop++] = ' ', Ans[Atop++] = ' ', Ans[Atop++] = ' ';
    }
    Ans[Atop++] = '[', Ans[Atop++] = now->c, Ans[Atop++] = ']';
    while(curr != NULL) {
        TriePrint(curr, dv+1);
        curr = curr->peer;
    }
    if(now->kid == NULL)    Ans[Atop] = '\0', puts(Ans), flag = 1, Atop = 0;
}
void InsTrie(Trie *tree, char s[]) {
    TrieNode *curr = tree->root, *prev = NULL, *temp, *p;
    int a;
    for(a = 0; s[a]; a++) {
        p = curr, curr = p->kid, prev = NULL;
        while(curr != NULL && curr->c < s[a])
            prev = curr, curr = curr->peer;
      
        if(curr == NULL) {
            temp = (TrieNode*)malloc(sizeof(TrieNode));
            temp->c = s[a], temp->kid = temp->peer = NULL;
            if(prev == NULL)    p->kid = temp;
            else    prev->peer = temp;
            curr = temp;
        }
        else {
            if(curr->c == s[a])    continue;
            temp = (TrieNode*)malloc(sizeof(TrieNode));
            temp->c = s[a], temp->kid = NULL;
            if(curr == p->kid)    p->kid = temp, temp->peer = curr;
            else    prev->peer = temp,    temp->peer = curr;
            curr = temp;
        }
    }
}

main() {
    int N;
    char s[10001];
    while(scanf("%d", &N) == 1) {
        Trie Tree;
        Trieinit(&Tree);
        getchar();
        while(N--)
            gets(s), InsTrie(&Tree, s);
        flag = 0, TriePrint(Tree.root, 0);
        TrieFree(Tree.root);
    }
    return 0;
}


[遞迴版(裸)]

/**********************************************************************************/
/*  Problem: a177 "逆逆向思考" from Trie                                     */
/*  Language: C                                                                   */
/*  Result: AC (680ms, 6668KB) on ZeroJudge                                       */
/*  Author: morris1028 at 2011-07-10 22:01:11                                     */
/**********************************************************************************/


#include<stdio.h>
#include<stdlib.h>
typedef struct TrieNode    {
    char c;
    struct TrieNode *kid, *peer;
}TrieNode;
typedef struct Trie    {
    struct TrieNode *root;
}Trie;

void Trieinit(Trie*);
void TrieFree(TrieNode*);
void InsTrie(Trie*, char s[]);
void TriePrint(TrieNode*, int);

void Trieinit(Trie *tree) {
    tree->root = (TrieNode*)malloc(sizeof(TrieNode));
    tree->root->c = ' ';
    tree->root->kid = tree->root->peer = NULL;
}
void TrieFree(TrieNode *now) {
    if(now == NULL)    return;
    TrieNode *curr = now->kid, *prev;
    while(curr != NULL) {
        prev = curr, curr = curr->peer;
        TrieFree(prev);
    }
    free(now);
}
int flag, Atop = 0;
char Ans[30001];
void TriePrint(TrieNode *now, int dv) {
    if(now == NULL)    return;
    TrieNode *curr = now->kid;
    if(flag == 1) {
        int a;
        for(a = 0, flag = 0; a < dv; a++)
            Ans[Atop++] = ' ', Ans[Atop++] = ' ', Ans[Atop++] = ' ';
    }
    Ans[Atop++] = '[', Ans[Atop++] = now->c, Ans[Atop++] = ']';
    while(curr != NULL) {
        TriePrint(curr, dv+1);
        curr = curr->peer;
    }
    if(now->kid == NULL)    Ans[Atop] = '\0', puts(Ans), flag = 1, Atop = 0;
}
void InsTrie(Trie *tree, char s[]) {
    TrieNode *curr = tree->root, *prev = NULL, *temp, *p;
    int a;
    for(a = 0; s[a]; a++) {
        p = curr, curr = p->kid, prev = NULL;
        while(curr != NULL && curr->c < s[a]) {
            if(curr->c < s[a])    prev = curr, curr = curr->peer;
        }
      
        if(curr == NULL) {
            temp = (TrieNode*)malloc(sizeof(TrieNode));
            temp->c = s[a], temp->kid = temp->peer = NULL;
            if(prev == NULL)    p->kid = temp;
            else    prev->peer = temp;
            curr = temp;
        }
        else {
            if(curr->c == s[a])    continue;
            temp = (TrieNode*)malloc(sizeof(TrieNode));
            temp->c = s[a], temp->kid = NULL;
            if(curr == p->kid)    p->kid = temp, temp->peer = curr;
            else    prev->peer = temp,    temp->peer = curr;
            curr = temp;
        }
    }
}

main() {
    int N;
    char s[10001];

    while(scanf("%d", &N) == 1) {
        Trie Tree;
        Trieinit(&Tree);
        while(N--)
            scanf("%s", s), InsTrie(&Tree, s);
        flag = 0, TriePrint(Tree.root, 0);
        TrieFree(Tree.root);
    }
    return 0;
}

台長: Morris
人氣(910) | 回應(0)| 推薦 (0)| 收藏 (0)| 轉寄
全站分類: 不分類 | 個人分類: 各類演算法與示範題目 |
此分類下一篇:鏈結 Stack (堆疊)
此分類上一篇:AVLTree (高度平衡樹)

是 (若未登入"個人新聞台帳號"則看不到回覆唷!)
* 請輸入識別碼:
請輸入圖片中算式的結果(可能為0) 
(有*為必填)
TOP
詳全文