码迷,mamicode.com
首页 > 其他好文 > 详细

通过trie树单词自动补全(二)

时间:2016-04-24 21:31:45      阅读:561      评论:0      收藏:0      [点我收藏+]

标签:

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, "\n");
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] == \0) {
148         error("insert fail, root or words is null");
149         return -1;
150     }
151     node_t *node = root;
152     node_t *tmp;
153     char *s = words;
154     while (*s != \0) {
155         if (node->child[*s - a] == NULL) {
156             tmp = createNode();
157             if (tmp == NULL) {
158                 goto err;
159             }
160             node->child[*s - a] = tmp;
161         }
162         node = node->child[*s - a];
163         s++;
164     }
165     node->count++;
166     memcpy(node->words, words, strlen(words));
167     return 0;
168 err:
169     return -1;
170 }
171 
172 void search_child(node_t *node, int client_sock) {
173     if (!node) {
174         error("search_child fail, node is null");
175         return;
176     }
177     int i;
178     if (node->count) {
179         send(client_sock, node->words, strlen(node->words), 0);
180                 send(client_sock, "|", 1, 0);
181     }
182     for (i = 0; i < MAX_CHILD; i++) {
183         if (node->child[i]) {
184             search_child(node->child[i], client_sock);
185         }
186     }
187 }
188 
189 /**
190  * search
191  */
192 int search(node_t *root, char *words, int client_sockfd) {
193     //--------------------------------fixme-------------------------------------
194     char *ps = words;
195     while (*ps != \0) {
196         if (*ps < a || *ps > z) {
197             *ps = \0;
198             break;
199         }
200         ps++;
201     }
202     //--------------------------------------------------------------------------
203     if (!root || words[0] == \0) {
204         error("search fail, root or words is null");
205         return -1;
206     }
207         debug("request query: %s", words);
208     char *s = words;
209     node_t *node = root;
210     while (*s != \0) {
211         if (node->child[*s - a] == NULL) {
212             break;
213         }
214         node = node->child[*s - a];
215         s++;
216     }
217     if (*s == \0) {
218 #if 0        
219         if (node->count == 0) {
220             printf("没有搜索到这个字符串,但是它是某个字符串的前缀\n");
221         } else {
222             printf("搜索到此字符串,出现次数为:%d\n", node->count);
223         }
224 #endif
225         search_child(node, client_sockfd);
226         
227     } else {
228 #if 0        
229         printf("没有搜索到这个字符串:%s, %d\n", words, strlen(words));
230 #endif
231     }
232     close(client_sockfd);
233 }
234 
235 /**
236  * free mem
237  */
238 void del(node_t *root) {
239     if (!root) {
240         error("del fail, root is null");
241         return;
242     }
243 
244     int i;
245     for (i = 0; i < MAX_CHILD; i++) {
246         if (root->child[i]) {
247             del(root->child[i]);
248         }
249     }
250     free(root);
251 
252 }
253 
254 /**
255  * load data from file
256  */
257 int load_data() {
258         global_root = createNode();
259         if(!global_root){
260                 return -1;
261         }
262     FILE *fp = fopen(DATA_PATH, "r");
263     if (!fp) {
264         error("open fail fail: %S", strerror(errno));
265         return -1;
266     }
267     char words[20];
268     while (!feof(fp) && fgets(words, sizeof (words), fp)) {
269         words[strlen(words) - 1] = \0;
270         insert(global_root, words);
271         memset(words, 0, sizeof (words));
272     }
273     debug("load_data success");
274     return 0;
275 }
276 
277 /**
278  * response the request
279  */
280 void accept_request(int client_sockfd){
281     char buf[20];
282     memset(buf, 0, sizeof(buf));
283     recv(client_sockfd, buf, sizeof(buf), 0);
284     search(global_root, buf, client_sockfd);
285     //close client connection
286     close(client_sockfd);
287 }
288 
289 int main(void) {
290     int server_sockfd = -1, client_sockfd = -1;
291     struct sockaddr_in client_addr;
292     memset(&client_addr, 0, sizeof (client_sockfd));
293     int addr_len = sizeof (client_sockfd);
294 
295     server_sockfd = startup();
296     if (server_sockfd < 0) {
297         return -1;
298     }
299 
300     //load data from file
301     load_data();
302 
303     //waitting for client
304     while (1) {
305         client_sockfd = accept(server_sockfd,
306                 (struct sockaddr *) &client_addr, &addr_len);
307         if(client_sockfd < 0){
308             error("accept fail, %s", strerror(errno));
309             return -1;
310         }
311         accept_request(client_sockfd);
312     }
313     
314     close(server_sockfd);
315     return 0;
316 }

 

sug.php

<?php

if($_GET[‘query‘]){
        $query = $_GET[‘query‘];
}else{
        exit(json_encode(array()));
}

$host = "127.0.0.1";
$port = "8080";

$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP) or die("Unable to create socket\n");
@socket_connect($socket, $host, $port) or die("Connect error.\n");

if ($err = socket_last_error($socket)){

        socket_close($socket);
        die(socket_strerror($err) . "\n");
}

$len = socket_write ($socket , $query, strlen($query));
$querys = "";
$ret = socket_read($socket, 100);
while($ret){
        $querys.=$ret;
        $ret = socket_read($socket, 100);
}
socket_close($socket);

$querysArr = explode("|", $querys);
array_pop($querysArr);

echo json_encode($querysArr);

 

效果:

http://www.idoushuo.com/sug.php?query=a

通过trie树单词自动补全(二)

标签:

原文地址:http://www.cnblogs.com/bai-jimmy/p/5428186.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!