通过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[];
} 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, "\n");
} /**
* 创建节点
*/
node_t *createNode(){
node_t *node = (node_t *)calloc(, 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 -;
}
node_t *node = root;
node_t *tmp;
char *s = words;
while(*s != '\0'){
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 ;
err:
return -;
} /**
* 搜索指定单词
*/
int search(node_t *root, char *words){
if(!root || words[] == '\0'){
error("search fail, root or words is null");
return -;
}
char *s = words;
node_t *node = root;
while(*s != '\0'){
if(node->child[*s - 'a'] == NULL){
break;
}
node = node->child[*s - 'a'];
s++;
}
if(*s == '\0'){
if(node->count == ){
printf("没有搜索到这个字符串,但是它是某个字符串的前缀\n");
}else{
printf("搜索到此字符串,出现次数为:%d\n", node->count);
} searchChild(node);
}else{
printf("没有搜索到这个字符串\n");
}
} /**
* 遍历出来的子节点是排序后的
*/
void searchChild(node_t *node){
if(!node){
error("searchChild fail, node is null");
return;
}
int i;
if(node->count){
printf("%s\n", node->words);
}
for(i = ; 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 = ; 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 -;
} //insert(root, str);
//search(root, "j");
FILE *fp = fopen("one.txt", "r");
if(!fp){
perror("open file fail");
}
char words[];
while(!feof(fp)){
fgets(words, sizeof(words), fp);
//去掉回车符
words[strlen(words) - ] = '\0';
insert(root, words);
memset(words, , sizeof(words));
} while(scanf("%s", words)){
search(root, words);
} del(root);
}
运行效果如下:

通过trie树实现单词自动补全的更多相关文章
- 通过trie树单词自动补全(二)
经常使用iciba进行单词查询, 关于他的搜索建议是通过单词前缀做的索引, 所以自己想动手实现下, 当然如果借助mysql的话,一条sql语句就能实现, 网上查询了下trie正适合做这个,所以通过C语 ...
- 关于在php中变量少写了一个$和页面不断转圈的问题排查和vim的自动补全方式
php中的所有变量都是页面级的, 即任何一个页面, 最多 都只能在一个文件 : 当前页面内使用, 不存在跨 文件/ 跨页面的 作用域的变量! 因此, 即使是 $GLOBALS 这个变量, 虽然叫全局 ...
- 我的Vim配置(自动补全/树形文件浏览)
配置文件的下载路径在这里 http://files.cnblogs.com/files/oloroso/vim.configure.xz.gz 这实际上是一个 xz 格式的文件,添加的 gz 文件后 ...
- IntelliJ IDEA 设置代码提示或自动补全的快捷键 (附IntelliJ IDEA常用快捷键)
修改方法如下: 点击 文件菜单(File) –> 点击 设置(Settings- Ctrl+Alt+S), –> 打开设置对话框. 在左侧的导航框中点击 KeyMap. 接着在右边的树型框 ...
- [LeetCode] Design Search Autocomplete System 设计搜索自动补全系统
Design a search autocomplete system for a search engine. Users may input a sentence (at least one wo ...
- [LeetCode] 642. Design Search Autocomplete System 设计搜索自动补全系统
Design a search autocomplete system for a search engine. Users may input a sentence (at least one wo ...
- Redis 实战 —— 08. 实现自动补全、分布式锁和计数信号量
自动补全 P109 自动补全在日常业务中随处可见,应该算一种最常见最通用的功能.实际业务场景肯定要包括包含子串的情况,其实这在一定程度上转换成了搜索功能,即包含某个子串的串,且优先展示前缀匹配的串.如 ...
- vim自动补全功能
1.首先下载一个插件:ctags 输入:sudo apt-get install ctags 2.Ctrl+n进行单词的自动补全
- Bash的自动补全
内置补全命令 Bash内置两个补全命令,分别是compgen和complete.compgen命令根据不同的参数,生成匹配单词的候选补全列表,例子如下: monster@monster-Z:~$ co ...
随机推荐
- css之颜色值、单位
颜色值 英文命令颜色:p{color:red;} RGB颜色:p{color:rgb(133,45,200);}每一项的值可以是 0~255 之间的整数,也可以是 0%~100% 的百分数.如:p{c ...
- sharepoint powershell 批量处理匿名访问
配置Web Application启用匿名访问 Add-PSSnapin -Name Microsoft.SharePoint.PowerShell -ErrorAction SilentlyCont ...
- RecyclerView-------MyAdapter代码
package com.example.administrator.recyclerview; import android.content.Context; import android.suppo ...
- iOS程序破解——class-dump获取头文件
原文在此:http://www.cnblogs.com/mddblog/p/4942894.html 一.简述 class-dump顾名思义,是用来dump目标对象class信息的工具.它根据oc的r ...
- IOS 多线程分类以及多线程的相关操作
直接附上援助链接:http://www.cnblogs.com/kenshincui/p/3983982.html 分享内容还关联到了生产者与消费者模式(其实看明白了整片文章,也就理解了生产者与消费者 ...
- 浅谈c#中的delegate和event了
一.开篇忏悔 对自己最拿手的编程语言C#,我想对你说声对不起,因为我到现在为止才明白c#中的delegate和event是怎么用的,惭愧那.好了,那就趁着阳光明媚的早晨简单来谈谈delegate和ev ...
- [C#6] 5-自动属性增强
0. 目录 C#6 新增特性目录 1. 老版本代码 internal class Person { public string Name { get; private set; } public in ...
- SQL SERVER 2000 迁移后SQL SERVER代理服务启动错误分析
公司有一个老系统,这个系统所用的数据库是SQL SERVER 2000,它所在的Dell服务器已经运行超过10年了,早已经过了保修服务期,最近几乎每周会出现一次故障,加之5月份另外一台服务器坏了两个硬 ...
- Unity贴图锯齿
之前在做一个Unity视频插件,发现渲染上去的贴图锯齿十分明显,开了抗锯齿也没用.最后在一次偶然的机会,发现了原来是贴图FilterMode设置有问题 之前用的是FilterMode.Point,后来 ...
- springMVC 拦截器如何做登录检查及页面跳转
一个非常简单的登录权限拦截器 问题一:登录页面的提交请求肯定是要过滤掉的,目前采用在xml里配置<mvc:mapping path="/supplier/*"/>来过滤 ...