经常使用iciba进行单词查询, 关于他的搜索建议是通过单词前缀做的索引, 所以自己想动手实现下, 当然如果借助mysql的话,一条sql语句就能实现, 网上查询了下trie正适合做这个,所以通过C语言自己做了个demo
sug.c
1 /* 2 * 单词自动补全功能 3 * File: search.c 4 * Author: baijianmin 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <string.h> 10 #include <errno.h> 11 #include <stdarg.h> 12 #include <time.h> 13 14 #include <sys/socket.h> 15 #include <netinet/in.h> 16 #include <arpa/inet.h> 17 18 #define MAX_CHILD 26 19 #define LISTEN_PORT 8080 20 #define LOG_DEBUG_PATH "./logs/debug.log" 21 #define LOG_ERROR_PATH "./logs/error.log" 22 #define DATA_PATH "one.txt" 23 24 /** 25 * define log level 26 */ 27 enum log_level { 28 DEBUG = 0, 29 ERROR = 1 30 }; 31 32 #define error(...) 33 logger(ERROR, __LINE__, __VA_ARGS__) 34 35 #define debug(...) 36 logger(DEBUG, __LINE__, __VA_ARGS__) 37 38 #define assert(expr, rc) 39 if(!(expr)){ 40 error(#expr"is null or 0"); 41 return rc; 42 } 43 44 /** 45 * trie node 46 */ 47 typedef struct node_s { 48 int count; 49 struct node_s *child[MAX_CHILD]; 50 char words[20]; 51 } node_t; 52 53 /** 54 * global var 55 */ 56 node_t *global_root; 57 58 59 /** 60 * get now timestr 61 */ 62 static void get_time(char *time_str, size_t len) { 63 time_t tt; 64 struct tm local_time; 65 time(&tt); 66 localtime_r(&tt, &local_time); 67 strftime(time_str, len, "%m-%d %H:%M:%S", &local_time); 68 } 69 70 /** 71 * log 72 */ 73 static void logger(int flag, int line, const char *fmt, ...) { 74 FILE *fp = NULL; 75 char time_str[20 + 1]; 76 va_list args; 77 get_time(time_str, sizeof(time_str)); 78 79 switch (flag) { 80 case DEBUG: 81 fp = fopen(LOG_DEBUG_PATH, "a"); 82 if (!fp) { 83 return; 84 } 85 fprintf(fp, "%s DEBUG (%d:%d) ", time_str, getpid(), line); 86 break; 87 case ERROR: 88 fp = fopen(LOG_ERROR_PATH, "a"); 89 if (!fp) { 90 return; 91 } 92 fprintf(fp, "%s ERROR (%d:%d) ", time_str, getpid(), line); 93 break; 94 default: 95 return; 96 } 97 98 va_start(args, fmt); 99 vfprintf(fp, fmt, args); 100 va_end(args); 101 fprintf(fp, " "); 102 103 fclose(fp); 104 return; 105 } 106 107 /** 108 * listen fro connections on a specified port 109 */ 110 int startup() { 111 int sockfd = -1; 112 struct sockaddr_in addr; 113 memset(&addr, 0, sizeof (addr)); 114 sockfd = socket(AF_INET, SOCK_STREAM, 0); 115 if (sockfd < 0) { 116 error("socket fail: %s", strerror(errno)); 117 return -1; 118 } 119 addr.sin_family = AF_INET; 120 addr.sin_port = htons(LISTEN_PORT); 121 addr.sin_addr.s_addr = htonl(INADDR_ANY); 122 if (bind(sockfd, (struct sockaddr *) &addr, sizeof (addr))) { 123 error("bind fail: %s", strerror(errno)); 124 return -1; 125 } 126 if (listen(sockfd, 5)) { 127 error("listen fail: %s", strerror(errno)); 128 return -1; 129 } 130 return sockfd; 131 } 132 133 /** 134 * create node 135 */ 136 node_t *createNode() { 137 node_t *node = (node_t *) calloc(1, sizeof (node_t)); 138 if (node == NULL) { 139 error("createNode fail: %s", strerror(errno)); 140 } 141 } 142 143 /** 144 * insert words 145 */ 146 int insert(node_t *root, char *words) { 147 if (!root || words[0] == '