通过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 ...
随机推荐
- ABySS非root权限安装
本文转自 http://yangl.net/2015/11/12/abyss_install/ ABySS: ABySS is a de novo, parallel, paired-end seq ...
- Java 四种线程池newCachedThreadPool,newFixedThreadPool,newScheduledThreadPool,newSingleThreadExecutor
介绍new Thread的弊端及Java四种线程池的使用,对Android同样适用.本文是基础篇,后面会分享下线程池一些高级功能. 1.new Thread的弊端执行一个异步任务你还只是如下new T ...
- stm32 usart 异步传输示例
STM32F103xE的USART异步数据传输示例 USART全称Universal Synchronous/Asynchronous Receiver/Transmitter,是一种可以进行同步/异 ...
- Atitit.atiagent agent分销系统 代理系统 设计文档
Atitit.atiagent agent分销系统 代理系统 设计文档 1. 启动项目1 2. 首也2 3. 登录功能2 4. 用户中心2 5. 充值查询3 6. 授权下级代理4 7. 我的提成5 ...
- springmvc+mybatis+spring 整合源码项目
A集成代码生成器 [正反双向(单表.主表.明细表.树形表,开发利器)+快速构建表单; freemaker模版技术 ,0个代码不用写,生成完整的一个模块,带页面.建表sql脚本,处理类,service等 ...
- django基础篇
Python的WEB框架有Django.Tornado.Flask 等多种,Django相较与其他WEB框架其优势为:大而全,框架本身集成了ORM.模型绑定.模板引擎.缓存.Session等诸多功能. ...
- iOS PresentViewControlle后,直接返回根视图
在开发中:用[self presentViewController:VC animated:YES completion:nil];实现跳转,多次跳转后,直接返回第一个. 例如: A presentV ...
- 初识JavaScript 变量, 操作符, 数组
这里讲的不会太多, 因为所有的语言都是一样的, 一些基本的东西, 所以就随便写写. 变量 变量就是可变的量, 编程角度理解就是用于存储某种/某些数值的存储器. 我们可以把变量具象理解为一个盒子, 而我 ...
- window.frameElement的使用
window.frameElement的使用: 返回嵌入当前window对象的元素(比如 <iframe> 或者 <object>),如果当前window对象已经是顶层窗口,则 ...
- SQLServer复制(二)--事务代理作业
之前的一篇已经介绍了如何配置复制,介绍了发布者.分发者和订阅者以及事务日志运行的简单关系.其中提到了复制代理,我们这篇将详细介绍复制代理,它是什么?在事务复制的步骤中起到了什么作用? 代理和工作 首先 ...