KevinACoder / Learning

GNU General Public License v3.0
5 stars 2 forks source link

trie #1

Closed KevinACoder closed 5 years ago

KevinACoder commented 5 years ago
//h
#define INIT_TRIE(t) trie t; init_trie(&t)
#define FREE_TRIE(t) reset_trie(&t);

typedef struct trie_node {
    bool                is_word;
    struct trie_node    *children[KEY_SET_NUM];
} trie_node;

typedef struct trie {
    trie_node           *root;
} trie;

void init_trie(trie *t);
void reset_trie(trie *t);
void insert_trie(trie *t, const char *word);
bool search_trie(trie *t, const char *word);
bool start_with_trie(trie *t, const char *prefix);

void test_tire();

#endif // !TRIE_H

//c
#include "trie.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

extern void err_exit(char* msg);
#define MEM_FAIL "fail to allocate memory"

static trie_node *new_trie_node() {
    trie_node *n = malloc(sizeof(trie_node));
    if (!n)
        err_exit(MEM_FAIL);

    n->is_word = false;
    memset(n->children, 0, sizeof(trie_node *)*KEY_SET_NUM);

    return n;
}

static void del_trie_node(trie_node *n) {
    //delet all childrens first
    for (int i = 0; i < KEY_SET_NUM; i++) {
        if (n->children[i]) {
            del_trie_node(n->children[i]);
            n->children[i] = NULL;
        }   
    }
    free(n);
}

void init_trie(trie *t) {
    t->root = new_trie_node();
}

void reset_trie(trie *t) {
    del_trie_node(t->root);
    t->root = NULL;
}

void insert_trie(trie *t, const char *word) {
    trie_node *cur = t->root;
    if (!cur)
        return;

    int word_len = strlen(word);
    for (int i = 0; i < word_len; i++) {
        int ix = word[i] - 'a';
        if (!cur->children[ix])
            cur->children[ix] = new_trie_node();

        cur = cur->children[ix];
    }
    cur->is_word = true;
}

static trie_node * find(trie *t, const char *prefix) {
    trie_node *cur = t->root;

    int word_len = strlen(prefix);
    for (int i = 0; i < word_len; i++) {
        cur = cur->children[prefix[i] - 'a'];
        if (!cur)
            break;
    }
    return cur;
}

bool search_trie(trie *t, const char *word) {
    trie_node *cur = find(t, word);
    return cur && cur->is_word;
}

bool start_with_trie(trie *t, const char *prefix) {
    return find(t, prefix) != NULL;
}

void test_tire() {
    const char *word = "banan";
    INIT_TRIE(t);
    insert_trie(&t, word);
    printf("has prefix %d", start_with_trie(&t, "ban"));
    FREE_TRIE(t);
}