• 通过trie树实现单词自动补全


    /**
     * 实现单词补全功能
     */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    #include <stdarg.h>
    
    #define MAX_CHILD 26
    
    #define error(...) 
            logger(stderr, __LINE__, __VA_ARGS__)
    
    #define notice(...) 
            logger(stdout, __LINE__, __VA_ARGS__)
    
    /**
     * 定义trie树节点
     */
    typedef struct node_s{
            int count;
            struct node_s *child[MAX_CHILD];
            char words[20];
    } node_t;
    
    /**
     * 日志
     */
    void logger(FILE *fp, int line, const char *fmt, ...){
            fprintf(fp, "[line]:%d | ", line);
            va_list ap;
            va_start(ap, fmt);
            vfprintf(fp, fmt, ap);
            va_end(ap);
            fprintf(fp, "
    ");
    }
    
    /**
     * 创建节点
     */
    node_t *createNode(){
            node_t *node = (node_t *)calloc(1, sizeof(node_t));
            if(node == NULL){
                    error("createNode fail, errno[%d]", errno);
            }
    }
    
    /**
     * 添加
     */
    int insert(node_t *root, char *words){
            if(!root || words[0] == ''){
                    error("insert fail, root or words is null");
                    return -1;
            }
            node_t *node = root;
            node_t *tmp;
            char *s = words;
            while(*s != ''){
                    if(node->child[*s - 'a'] == NULL){
                            tmp = createNode();
                            if(tmp == NULL){
                                    goto err;
                            }
                            node->child[*s - 'a'] = tmp;
                    }
                    node = node->child[*s - 'a'];
                    s++;
            }
            node->count++;
            memcpy(node->words, words, strlen(words));
            notice("insert success, words = %s", words);
            return 0;
    err:
            return -1;
    }
    
    /**
     * 搜索指定单词
     */
    int search(node_t *root, char *words){
            if(!root || words[0] == ''){
                    error("search fail, root or words is null");
                    return -1;
            }
            char *s = words;
            node_t *node = root;
            while(*s != ''){
                    if(node->child[*s - 'a'] == NULL){
                            break;
                    }
                    node = node->child[*s - 'a'];
                    s++;
            }
            if(*s == ''){
                    if(node->count == 0){
                            printf("没有搜索到这个字符串,但是它是某个字符串的前缀
    ");
                    }else{
                            printf("搜索到此字符串,出现次数为:%d
    ", node->count);
                    }
    
                    searchChild(node);
            }else{
                    printf("没有搜索到这个字符串
    ");
            }
    }
    
    /**
     * 遍历出来的子节点是排序后的
     */
    void searchChild(node_t *node){
            if(!node){
                    error("searchChild fail, node is null");
                    return;
            }
            int i;
            if(node->count){
                    printf("%s
    ", node->words);
            }
            for(i = 0; i < MAX_CHILD; i++){
                    if(node->child[i]){
                            searchChild(node->child[i]);
                    }
            }
    }
    
    /**
     * 递归回收内存
     */
    void del(node_t *root){
            if(!root){
                    error("del fail, root is null");
                    return;
            }
    
            int i;
            for(i = 0; i < MAX_CHILD; i++){
                    if(root->child[i]){
                            del(root->child[i]);
                    }
            }
            free(root);
    
    }
    
    int main(){
            char *str = "jimmy";
            node_t *root = createNode();
            if(!root){
                    return -1;
            }
    
            //insert(root, str);
            //search(root, "j");
            FILE *fp = fopen("one.txt", "r");
            if(!fp){
                    perror("open file fail");
            }
            char words[20];
            while(!feof(fp)){
                    fgets(words, sizeof(words), fp);
                    //去掉回车符
                    words[strlen(words) - 1] = '';
                    insert(root, words);
                    memset(words, 0, sizeof(words));
            }
    
            while(scanf("%s", words)){
                    search(root, words);
            }
    
    
            del(root);
    }

    运行效果如下:

  • 相关阅读:
    MySQL中如何使用布尔类型【转】
    你所不知道的Android Studio调试技巧【转】
    设计模式之工厂模式(factory pattern)【转】
    layuiadmin+tp5后台内容管理系统【转】
    PHPStorm怎么修改选中的背景颜色呢?【转】
    PHP保留两位小数的几种方法【转】
    jquery的css()函数同时设置多个css属性值
    Flutter text设置行间距【转】
    Flutter入门-布局Container、Padding、Align、Center【转】
    redis下载地址
  • 原文地址:https://www.cnblogs.com/bai-jimmy/p/5426161.html
Copyright © 2020-2023  润新知