解决用户在搜索引擎乱输入,无空格或间接输入,进行分割
现在经常会有一个用户在搜索引擎中输入不加空格或者分割符的,近来写了一个小小的代码,用一个词库,来匹配用户输入的单词或者是其他的东西,最后以空格分割输出。以下是一个简单的ruby程序。利用hash进行索引,查询速更快。
1 $stack = [] 2 $scan_str = File.read("#{File.dirname(__FILE__)}/word.txt").scan(/(.*)\[/) 3 $a = "" #用来装不能分割单词的情况 4 def get_word 5 puts "请输入需要搜索的内容" 6 sum = 0 7 #for i in 0..100 8 str = gets.chomp() 9 #str = "ukcfefweiufweifhf" 10 t1 = Time.new 11 h = Hash.new() 12 for i in 0..$scan_str.length-1 13 h["#{$scan_str[i][0]}"]=1 14 end 15 if h.key?str 16 puts "你搜索的结果为:#{str}" 17 return 18 else 19 i = 0 #递归开始的位置 20 j = 0 #数组下标 21 k = 1 #每次开始的位置 22 fun(str,i,j,k) 23 if $a.length>0&&$stack.length==0 24 puts "输入的单词可能错误哦 可能的搜索为结果:#{$a}" 25 end 26 if $a.length==0 27 puts "没有符合的" 28 end 29 $stack = [] 30 $a = "" 31 t2 = Time.new 32 c = t2-t1 33 puts "执行代码的时间为:#{t2-t1}" 34 #sum = sum + c 35 end 36 #end 37 #puts "总时间为:#{sum}" 38 #puts "平均时间为:#{sum/100}" 39 end 40 41 def fun(str,i,j,k) 42 h = Hash.new() 43 for z in 0..$scan_str.length-1 44 h["#{$scan_str[z][0]}"]=1 45 end 46 if str.length.eql?$stack.join("").length #数组转string join("") 47 puts "搜索的结果为:\n #{$stack.join(" ")}" #以空格分开 输出 48 return 49 end 50 q = [] 51 while !str.length.eql?$stack.join("").length 52 q[j]=str[i,k] 53 #puts "j = #{j}, k = #{k}" 54 #puts "fun的str:#{str}" 55 #puts "fun的q:#{q}" 56 #puts "第#{j}个单词:#{q[j]}" 57 if h.key?q[j] 58 #puts "找到单词:#{q[j]},找到啦 找到啦" 59 $stack.push(q[j]) 60 $stack.push("") 61 #puts "匹配入栈的值:#{$stack}" 62 $a = q[j] 63 fun(str,$stack.join("").length,j+1,1) 64 #puts "栈的值:#{$stack}" 65 end 66 #puts "q[str.length-1]:#{q[str.length-1]}" 67 j = j+1 68 k = k+1 69 if q[str.length-1]!=nil #如果后面的单词不匹配 70 if !h.key?q[str.length-1] 71 $stack.pop 72 $stack.pop 73 return 74 end 75 end 76 end 77 end
但是考虑到用ruby的话,运行时间上来看还是没有用c写的快,于是用了linux-c socket编程写了两个程序--客户端+服务器(客户端负责输入,服务器负责查询最后将结果传回客户端先采用udp,可以多个客户端调用,因为udp是无序的)(更推荐)
#include <netinet/in.h> // for sockaddr_in #include <sys/types.h> // for socket #include <sys/socket.h> // for socket #include <stdio.h> #include <stdlib.h> // for exit #include <string.h> // for bzero #include <time.h> #define PORT 6996 #define BUFFER_SIZE 1024 #define N 1024 char *words[20000]; int main(int argc, char **argv) { clock_t start, end; char str[N]; int n=0; FILE *fp; if( (fp=fopen("key_string.txt","r")) == NULL ){ printf("Cannot open file, press enter to exit!\n"); return ; } while(fgets(str, N, fp) != NULL){ if(strlen(str)==N) continue; words[n] = (char*)malloc(1024*sizeof(char)); //每次动态开一个 sscanf(str,"%[^\n]",words[n]); //匹配 n++; } n--; printf("key_string.txt的词数有:%d\n",n); if (argc != 2) { printf("Please Input Server IP Address\n"); exit(1); } int client_socket = socket(AF_INET,SOCK_DGRAM,0); if( client_socket < 0) { printf("Create Socket Failed!\n"); exit(1); } //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口 struct sockaddr_in server_addr; bzero(&server_addr,sizeof(server_addr)); server_addr.sin_family = AF_INET; server_addr.sin_port = htons(PORT); server_addr.sin_addr.s_addr=inet_addr(argv[1]); while(n!=-1){ char send_buffer[BUFFER_SIZE]; bzero(send_buffer,BUFFER_SIZE); strcpy(send_buffer,words[n]); printf("-----------------------------------------------------------------\n"); printf("第%d的是:%s\n",n,words[n]); //向服务器发送buffer中的数据 if(sendto(client_socket,send_buffer,BUFFER_SIZE,0,(struct sockaddr *)&server_addr,sizeof(server_addr))<0){ printf("Server Send Failed\n"); break; } //从服务器接收数据到buffer中 char recv_buffer[BUFFER_SIZE]; bzero(recv_buffer,BUFFER_SIZE); int length = 0; length = recvfrom(client_socket,recv_buffer,BUFFER_SIZE,0,NULL,NULL); if(length < 0) { printf("Recieve Data From Server Failed!\n" ); break; } printf("Search Result -- %s \n",recv_buffer); bzero(recv_buffer,BUFFER_SIZE); printf("此时n的值为:%d\n",n); n--; //关闭socket } fclose(fp); close(client_socket); return 0; }
#include <netinet/in.h> // for sockaddr_in #include <sys/types.h> // for socket #include <sys/socket.h> // for socket #include <stdio.h> #include <stdlib.h> // for exit #include <string.h> // for bzero #define PORT 6996 #define LISTEN_COUNT 20 #define BUFFER_SIZE 1024 #define N 60 #define HASHSIZE 2000000 //开辟一个数组 char* words[1600000]; char* search[BUFFER_SIZE]; int k = 0,size=0;//size用来判断当前移动单词的位置 typedef struct _node{ char * word; struct _node *next; }node; static node* hashtab[HASHSIZE]; //初始化 void inithashtab(){ int i; for(i=0;i<HASHSIZE;i++) hashtab[i]=NULL; } //计算hash unsigned int hash(char *s){ unsigned int h=0; for(;*s;s++){ h=*s+h*N; } return h%HASHSIZE; } //找单词 node* lookup(char *n){ unsigned int hi=hash(n); node* np=hashtab[hi]; for( ;np!=NULL;np=np->next){ if(!strcmp(np->word,n)&&np->word!=NULL&&n!=NULL){ //是否等 return np; } } return NULL; } //存单词 char* save(char *o){ int l=strlen(o)+1; char *ns=(char*)malloc(l*sizeof(char)); strcpy(ns,o); if(ns==NULL) return NULL; else return ns; } //获取 根据单词 char* get(char* word){ node* n=lookup(word); if(n==NULL) return NULL; else return n->word; } //插入 int insert(char* word){ unsigned int hi; node* np; if((np=lookup(word))==NULL){ //先找 hi=hash(word); //找不到 再分配 np=(node*)malloc(sizeof(node)); if(np==NULL) return 0; np->word=save(word); //保存 if(np->word==NULL) return 0; np->next=hashtab[hi]; //插入的时候 如果发现冲突 就往链表里扔 hashtab[hi]=np; } return 1; } //分割单词 找单词 int devide(char* word,int start){ char *q; char a[BUFFER_SIZE]={},instead; size = strlen(word); while(*word&&size>0){ instead = *word; a[start] = instead; //printf("a的值:%s\n",a); q = a; if(get(a)){ printf("找到啦~这个单词是:%s\n",a); search[k++] = q; search[k++] = " "; word++; devide(word,0); word--; } start++; word++; if(strlen(word)==0){ if(!get(q)){ search[--k]=""; search[--k]=""; } } } if(k<=0){ //里面一个都没有 return 0; } return 1; } int main(int argc, char **argv) { FILE *fp; char str[N+1]; int i = 0,n=0,s,count=0,flag=0,out_length; int c=0; if( (fp=fopen("yes.txt","r")) == NULL ){ printf("Cannot open file, press enter to exit!\n"); return ; } while(fgets(str, N, fp) != NULL){ words[n] = (char*)malloc(50*sizeof(char)); //每次动态开一个 sscanf(str,"%[^:]",words[n]); //匹配 //printf("第%d个单词是:%s\n",n,words[n]); n++; } printf("统计单词数:%d\n",n); printf("-----------------------------------------------------------------\n"); s = sizeof(words) / sizeof(words[0]); inithashtab(); for(i=0;i<s;i++){ if(words[i]==NULL) break; insert(words[i]); } //server_socket代表服务器socket int server_socket = socket(AF_INET,SOCK_DGRAM,0); if( server_socket < 0) { printf("Create Socket Failed!"); exit(1); } struct sockaddr_in server_addr; bzero(&server_addr,sizeof(server_addr)); //把一段内存区的内容清零 server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htonl(INADDR_ANY);//INADDR_ANY表示自动获取本机地址 server_addr.sin_port = htons(PORT); if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)) <0) { printf("Server Bind Port : %d Failed!", PORT); exit(1); } struct sockaddr_in cli_addr; int cli_size = sizeof(cli_addr); char send_buffer[BUFFER_SIZE]; char recv_buffer[BUFFER_SIZE]; while (1) //服务器端要一直运行 { bzero(recv_buffer,BUFFER_SIZE); bzero(send_buffer,BUFFER_SIZE); k = 0,size=0; int length = recvfrom(server_socket,recv_buffer,sizeof(recv_buffer),0,(struct sockaddr *)&cli_addr,&cli_size); if(length < 0 ){ printf("Server Recv Failed\n"); break; } printf("收到:%s\n",recv_buffer); if(get(recv_buffer)){ //索引判断是否存在 printf("Result -- %s !\n",get(recv_buffer)); if(sendto(server_socket,recv_buffer,sizeof(recv_buffer),0,(struct sockaddr *)&cli_addr,cli_size)<0){ printf("Server Send Failed\n"); break; } continue; } else flag = devide(recv_buffer,0); if(flag){ printf("Result -- "); for(i=0;i<k-1;i++){ printf("%s",search[i]); strcat(send_buffer,search[i]); //拼接 指针数组送不过去 } printf("\n"); if(sendto(server_socket,send_buffer,sizeof(send_buffer),0,(struct sockaddr *)&cli_addr,cli_size)<0){ printf("Server Send Failed\n"); break; } } else{ printf("No Search ! \n"); bzero(send_buffer,BUFFER_SIZE); strcat(send_buffer,"No Find ! "); if(sendto(server_socket,send_buffer,sizeof(send_buffer),0,(struct sockaddr *)&cli_addr,cli_size)<0) { printf("Server Send Failed\n"); break; } } printf("-----------------------------------------------------------------\n"); } for(i=0;i<n;i++){ free(words[i]); //释放空间 } fclose(fp); //关闭监听用的socket close(server_socket); return 0; }
tcp的服务器和客户端,服务器可以采用fork编程,通过父子进程实现多个客户端的调用
1 #include <netinet/in.h> // for sockaddr_in 2 #include <sys/types.h> // for socket 3 #include <sys/socket.h> // for socket 4 #include <stdio.h> 5 #include <stdlib.h> // for exit 6 #include <string.h> // for bzero 7 #include <time.h> 8 #define PORT 8558 9 #define BUFFER_SIZE 1024 10 #define N 1024 11 12 char *words[20000]; 13 14 int main(int argc, char **argv) 15 { 16 clock_t start, end; 17 char str[N]; 18 int n=0; 19 20 FILE *fp; 21 if( (fp=fopen("key_string.txt","r")) == NULL ){ 22 printf("Cannot open file, press enter to exit!\n"); 23 return ; 24 } 25 while(fgets(str, N, fp) != NULL){ 26 if(strlen(str)==N) 27 continue; 28 words[n] = (char*)malloc(1024*sizeof(char)); //每次动态开一个 29 sscanf(str,"%[^\n]",words[n]); //匹配 30 n++; 31 } 32 n--; 33 34 printf("key_string.txt的词数有:%d\n",n); 35 if (argc != 2) 36 { 37 printf("Please Input Server IP Address\n"); 38 exit(1); 39 } 40 41 //设置一个socket地址结构client_addr 42 struct sockaddr_in client_addr; 43 bzero(&client_addr,sizeof(client_addr)); 44 client_addr.sin_family = AF_INET; //internet协议族 PF_INET 也可以 45 client_addr.sin_addr.s_addr = inet_addr(argv[1]); 46 client_addr.sin_port = htons(0); //0表示让系统自动分配一个空闲端口 47 48 int client_socket = socket(AF_INET,SOCK_STREAM,0); 49 if( client_socket < 0) 50 { 51 printf("Create Socket Failed!\n"); 52 exit(1); 53 } 54 55 //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口 56 struct sockaddr_in server_addr; 57 bzero(&server_addr,sizeof(server_addr)); 58 server_addr.sin_family = AF_INET; 59 server_addr.sin_port = htons(PORT); 60 int server_addr_length = sizeof(server_addr); 61 //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接 62 //三次握手 63 if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0) 64 { 65 printf("Can Not Connect To %s!\n",argv[1]); 66 exit(1); 67 } 68 69 while(n!=-1){ 70 char input[BUFFER_SIZE]={}; 71 strcpy(input,words[n]); 72 printf("-----------------------------------------------------------------\n"); 73 printf("第%d的是:%s\n",n,words[n]); 74 char buffer[BUFFER_SIZE]; 75 bzero(buffer,BUFFER_SIZE); 76 77 //向服务器发送buffer中的数据 78 if(send(client_socket,input,BUFFER_SIZE,0)<0){ 79 printf("Server Send Failed\n"); 80 break; 81 } 82 //从服务器接收数据到buffer中 83 bzero(buffer,BUFFER_SIZE); 84 int length = 0; 85 length = recv(client_socket,buffer,BUFFER_SIZE,0); 86 if(length < 0) 87 { 88 printf("Recieve Data From Server Failed!\n" ); 89 break; 90 } 91 printf("Search Result -- %s \n",buffer); 92 bzero(buffer,BUFFER_SIZE); 93 printf("此时n的值为:%d\n",n); 94 n--; 95 //关闭socket 96 97 } 98 fclose(fp); 99 close(client_socket); 100 return 0; 101 }
#include <netinet/in.h> // for sockaddr_in #include <sys/types.h> // for socket #include <sys/socket.h> // for socket #include <stdio.h> #include <stdlib.h> // for exit #include <string.h> // for bzero #define PORT 8558 #define LISTEN_COUNT 20 #define BUFFER_SIZE 1024 #define N 60 #define HASHSIZE 2000000 //开辟一个数组 char* words[1600000]; char* search[BUFFER_SIZE]; int k = 0,size=0;//size用来判断当前移动单词的位置 typedef struct _node{ char * word; struct _node *next; }node; static node* hashtab[HASHSIZE]; //初始化 void inithashtab(){ int i; for(i=0;i<HASHSIZE;i++) hashtab[i]=NULL; } //计算hash unsigned int hash(char *s){ unsigned int h=0; for(;*s;s++){ h=*s+h*N; } return h%HASHSIZE; } //找单词 node* lookup(char *n){ unsigned int hi=hash(n); node* np=hashtab[hi]; for( ;np!=NULL;np=np->next){ if(!strcmp(np->word,n)&&np->word!=NULL&&n!=NULL){ //是否等 return np; } } return NULL; } //存单词 char* save(char *o){ int l=strlen(o)+1; char *ns=(char*)malloc(l*sizeof(char)); strcpy(ns,o); if(ns==NULL) return NULL; else return ns; } //获取 根据单词 char* get(char* word){ node* n=lookup(word); if(n==NULL) return NULL; else return n->word; } //插入 int insert(char* word){ unsigned int hi; node* np; if((np=lookup(word))==NULL){ //先找 hi=hash(word); //找不到 再分配 np=(node*)malloc(sizeof(node)); if(np==NULL) return 0; np->word=save(word); //保存 if(np->word==NULL) return 0; np->next=hashtab[hi]; //插入的时候 如果发现冲突 就往链表里扔 hashtab[hi]=np; } return 1; } //分割单词 找单词 int devide(char* word,int start){ char *q; char a[BUFFER_SIZE]={},instead; size = strlen(word); while(*word&&size>0){ instead = *word; a[start] = instead; //printf("a的值:%s\n",a); q = a; if(get(a)){ printf("找到啦~这个单词是:%s\n",a); search[k++] = q; search[k++] = " "; word++; devide(word,0); word--; } start++; word++; if(strlen(word)==0){ if(!get(q)){ search[--k]=""; search[--k]=""; } } } if(k<=0){ //里面一个都没有 return 0; } return 1; } int main(int argc, char **argv) { FILE *fp; char str[N+1]; int i = 0,n=0,s,count=0,flag=0,out_length; int c=0; if( (fp=fopen("yes.txt","r")) == NULL ){ printf("Cannot open file, press enter to exit!\n"); return ; } while(fgets(str, N, fp) != NULL){ words[n] = (char*)malloc(50*sizeof(char)); //每次动态开一个 sscanf(str,"%[^:]",words[n]); //匹配 //printf("第%d个单词是:%s\n",n,words[n]); n++; } printf("统计单词数:%d\n",n); printf("-----------------------------------------------------------------\n"); s = sizeof(words) / sizeof(words[0]); inithashtab(); for(i=0;i<s;i++){ if(words[i]==NULL) break; insert(words[i]); } //设置一个socket地址结构server_addr struct sockaddr_in server_addr; bzero(&server_addr,sizeof(server_addr)); //把一段内存区的内容清零 server_addr.sin_family = AF_INET; server_addr.sin_addr.s_addr = htons(INADDR_ANY);//INADDR_ANY表示自动获取本机地址 server_addr.sin_port = htons(PORT); //server_socket代表服务器socket int server_socket = socket(AF_INET,SOCK_STREAM,0); if( server_socket < 0) { printf("Create Socket Failed!"); exit(1); } //把socket和socket地址结构联系起来 if( bind(server_socket,(struct sockaddr*)&server_addr,sizeof(server_addr)) <0) { printf("Server Bind Port : %d Failed!", PORT); exit(1); } //server_socket用于监听 if ( listen(server_socket, LISTEN_COUNT) <0) { printf("Server Listen Failed!"); exit(1); } while(1){//服务器端要一直运行 printf("wating for client to connect!\n"); struct sockaddr_in client_addr; socklen_t cliaddr_len = sizeof(client_addr); int new_server_socket = accept(server_socket,(struct sockaddr*)&client_addr,&cliaddr_len); if ( new_server_socket < 0) { printf("Server Accept Failed!\n"); exit(1); } printf("wating for client to connect accept success!\n"); pid_t pid = fork(); if(pid < 0){ perror("fork error"); exit(1); }else if(pid ==0){ //close(server_socket);//关闭的是父进程的 char buffer[BUFFER_SIZE]; bzero(buffer, BUFFER_SIZE); while (recv(new_server_socket,buffer,BUFFER_SIZE,0)>0) { k = 0,size=0,out_length=0; printf("收到:%s\n",buffer); if(get(buffer)){ //索引判断是否存在 printf("Result -- %s !\n",get(buffer)); if(send(new_server_socket,buffer,BUFFER_SIZE,0)<0){ printf("Server Send Failed\n"); break; } continue; } else flag = devide(buffer,0); if(flag){ char output[BUFFER_SIZE]={}; printf("Result -- "); for(i=0;i<k-1;i++){ printf("%s",search[i]); strcat(output,search[i]); //拼接 指针数组送不过去 } out_length = strlen(output); printf("\n"); if(send(new_server_socket,output,out_length,0)<0){ printf("Server Send Failed\n"); break; } } else{ printf("No Search ! \n"); char no[BUFFER_SIZE]={}; strcat(no,"No Find ! "); int no_find_length = sizeof(no); if(send(new_server_socket,no,no_find_length,0)<0) { printf("Server Send Failed\n"); break; } } printf("-----------------------------------------------------------------\n"); } } else if(pid >0){ //父进程 close(new_server_socket); } } close(server_socket); for(i=0;i<n;i++){ free(words[i]); //释放空间 } fclose(fp); //关闭监听用的socket close(server_socket); return 0; }
tcp的服务器和客户端,服务器可以采用select这个函数句柄来实现多个客户端的调用(更推荐)
1 #include <netinet/in.h> // for sockaddr_in 2 #include <sys/types.h> // for socket 3 #include <sys/socket.h> // for socket 4 #include <stdio.h> 5 #include <stdlib.h> // for exit 6 #include <string.h> // for bzero 7 #include <time.h> 8 #define PORT 7878 9 #define BUFFER_SIZE 1024 10 #define N 1024 11 12 char *words[20000]; 13 14 int main(int argc, char **argv) 15 { 16 clock_t start, end; 17 char str[N]; 18 int n=0; 19 20 FILE *fp; 21 if( (fp=fopen("key_string.txt","r")) == NULL ){ 22 printf("Cannot open file, press enter to exit!\n"); 23 return ; 24 } 25 while(fgets(str, N, fp) != NULL){ 26 if(strlen(str)==N) 27 continue; 28 words[n] = (char*)malloc(1024*sizeof(char)); //每次动态开一个 29 sscanf(str,"%[^\n]",words[n]); //匹配 30 n++; 31 } 32 n--; 33 34 printf("key_string.txt的词数有:%d\n",n); 35 if (argc != 2) 36 { 37 printf("Please Input Server IP Address\n"); 38 exit(1); 39 } 40 41 //设置一个socket地址结构client_addr 42 struct sockaddr_in client_addr; 43 bzero(&client_addr,sizeof(client_addr)); 44 client_addr.sin_family = AF_INET; //internet协议族 PF_INET 也可以 45 client_addr.sin_addr.s_addr = inet_addr(argv[1]); 46 client_addr.sin_port = htons(0); //0表示让系统自动分配一个空闲端口 47 48 int client_socket = socket(AF_INET,SOCK_STREAM,0); 49 if( client_socket < 0) 50 { 51 printf("Create Socket Failed!\n"); 52 exit(1); 53 } 54 55 //设置一个socket地址结构server_addr,代表服务器的internet地址, 端口 56 struct sockaddr_in server_addr; 57 bzero(&server_addr,sizeof(server_addr)); 58 server_addr.sin_family = AF_INET; 59 server_addr.sin_port = htons(PORT); 60 int server_addr_length = sizeof(server_addr); 61 //向服务器发起连接,连接成功后client_socket代表了客户机和服务器的一个socket连接 62 //三次握手 63 if(connect(client_socket,(struct sockaddr*)&server_addr, server_addr_length) < 0) 64 { 65 printf("Can Not Connect To %s!\n",argv[1]); 66 exit(1); 67 } 68 69 while(n!=-1){ 70 char input[BUFFER_SIZE]={}; 71 72 strcpy(input,words[n]); 73 printf("-----------------------------------------------------------------\n"); 74 printf("第%d的是:%s\n",n,words[n]); 75 char buffer[BUFFER_SIZE]; 76 bzero(buffer,BUFFER_SIZE); 77 78 //向服务器发送buffer中的数据 79 if(send(client_socket,input,BUFFER_SIZE,0)<0){ 80 printf("Server Send Failed\n"); 81 break; 82 } 83 //从服务器接收数据到buffer中 84 bzero(buffer,BUFFER_SIZE); 85 int length = 0; 86 length = recv(client_socket,buffer,BUFFER_SIZE,0); 87 if(length < 0) 88 { 89 printf("Recieve Data From Server Failed!\n" ); 90 break; 91 } 92 printf("Search Result -- %s \n",buffer); 93 bzero(buffer,BUFFER_SIZE); 94 printf("此时n的值为:%d\n",n); 95 n--; 96 //关闭socket 97 98 } 99 fclose(fp); 100 close(client_socket); 101 return 0; 102 }
1 #include <netinet/in.h> // for sockaddr_in 2 #include <sys/types.h> // for socket 3 #include <sys/socket.h> // for socket 4 #include <stdio.h> 5 #include <stdlib.h> // for exit 6 #include <string.h> // for bzero 7 #include <sys/select.h> 8 #include <sys/time.h> 9 #include <unistd.h> 10 #include <fcntl.h> 11 12 #define PORT 7878 13 #define LISTEN_COUNT 20 14 #define BUFFER_SIZE 1024 15 16 #define N 60 17 #define HASHSIZE 2000000 //数组长度 18 19 char* words[1600000]; 20 char* search[BUFFER_SIZE]; 21 int k = 0,size=0;//size用来判断当前移动单词的位置 22 23 typedef struct _node{ 24 char * word; 25 struct _node *next; 26 }node; 27 28 static node* hashtab[HASHSIZE]; 29 //初始化 30 void inithashtab(){ 31 int i; 32 for(i=0;i<HASHSIZE;i++) 33 hashtab[i]=NULL; 34 } 35 //计算hash 36 unsigned int hash(char *s){ 37 unsigned int h=0; 38 for(;*s;s++){ 39 h=*s+h*N; 40 } 41 return h%HASHSIZE; 42 } 43 //找单词 44 node* lookup(char *n){ 45 unsigned int hi=hash(n); 46 node* np=hashtab[hi]; 47 for( ;np!=NULL;np=np->next){ 48 if(!strcmp(np->word,n)&&np->word!=NULL&&n!=NULL){ //是否等 49 return np; 50 } 51 } 52 return NULL; 53 } 54 //存单词 55 char* save(char *o){ 56 int l=strlen(o)+1; 57 char *ns=(char*)malloc(l*sizeof(char)); 58 strcpy(ns,o); 59 if(ns==NULL) 60 return NULL; 61 else 62 return ns; 63 } 64 //获取 根据单词 65 char* get(char* word){ 66 node* n=lookup(word); 67 if(n==NULL) 68 return NULL; 69 else 70 return n->word; 71 } 72 //插入 73 int insert(char* word){ 74 unsigned int hi; 75 node* np; 76 if((np=lookup(word))==NULL){ //先找 77 hi=hash(word); //找不到 再分配 78 np=(node*)malloc(sizeof(node)); 79 if(np==NULL) 80 return 0; 81 np->word=save(word); //保存 82 if(np->word==NULL) 83 return 0; 84 np->next=hashtab[hi]; //插入的时候 如果发现冲突 就往链表里扔 85 hashtab[hi]=np; 86 } 87 return 1; 88 } 89 //分割单词 找单词 90 int devide(char* word,int start){ 91 char *q; 92 char a[BUFFER_SIZE]={},instead; 93 size = strlen(word); 94 while(*word&&size>0){ 95 instead = *word; 96 a[start] = instead; 97 //printf("a的值:%s\n",a); 98 q = a; 99 if(get(a)){ 100 printf("找到啦~这个单词是:%s\n",a); 101 search[k++] = q; 102 search[k++] = " "; 103 word++; 104 devide(word,0); 105 word--; 106 } 107 start++; 108 word++; 109 if(strlen(word)==0){ 110 if(!get(q)){ 111 search[--k]=""; 112 search[--k]=""; 113 } 114 } 115 } 116 if(k<=0){ //里面一个都没有 117 return 0; 118 } 119 return 1; 120 } 121 122 int mz_ipv4_tcp_create_socket(void) 123 { 124 int listenfd, sockfd, opt = 1; 125 struct sockaddr_in server, client; 126 socklen_t len; 127 listenfd = socket(AF_INET, SOCK_STREAM, 0); 128 129 if(listenfd < 0){ 130 perror("Create socket fail."); 131 return -1; 132 } 133 134 bzero(&server, sizeof(server)); 135 server.sin_family = AF_INET; 136 server.sin_port = htons(PORT); 137 server.sin_addr.s_addr = htonl(INADDR_ANY); 138 139 len = sizeof(struct sockaddr); 140 if(bind(listenfd, (struct sockaddr *)&server, len)<0){ 141 perror("bind error"); 142 return -1; 143 } 144 145 listen(listenfd, LISTEN_COUNT); 146 147 return listenfd; 148 } 149 150 151 int main(int argc, char *argv[]) 152 { 153 FILE *fp; 154 char str[N+1]; 155 int j = 0,n=0,s; 156 int c=0; 157 158 if( (fp=fopen("yes.txt","r")) == NULL ){ 159 printf("Cannot open file, press enter to exit!\n"); 160 return ; 161 } 162 while(fgets(str, N, fp) != NULL){ 163 words[n] = (char*)malloc(50*sizeof(char)); //每次动态开一个 164 sscanf(str,"%[^:]",words[n]); //匹配 165 //printf("第%d个单词是:%s\n",n,words[n]); 166 n++; 167 } 168 169 printf("统计单词数:%d\n",n); 170 printf("-----------------------------------------------------------------\n"); 171 s = sizeof(words) / sizeof(words[0]); 172 inithashtab(); 173 for(j=0;j<s;j++){ 174 if(words[j]==NULL) 175 break; 176 insert(words[j]); 177 } 178 179 int listenfd, sockfd; 180 struct sockaddr_in server, client; 181 int bytes =0 ; 182 fd_set global_rdfs,current_rdfs; 183 int maxfd; 184 int i; 185 int z; 186 int out_length,flag; 187 char buffer[BUFFER_SIZE]; 188 189 socklen_t cli_len = sizeof(struct sockaddr_in); 190 191 listenfd = mz_ipv4_tcp_create_socket(); 192 FD_ZERO(&global_rdfs); 193 FD_SET(listenfd, &global_rdfs); 194 maxfd = listenfd; 195 while(1){ 196 k=0,size=0,out_length=0; 197 current_rdfs = global_rdfs; 198 if(select(maxfd + 1, ¤t_rdfs, NULL, NULL, NULL)<0){ 199 perror("select error.\n"); 200 return -1; 201 } 202 for(i = 0; i <= maxfd; i++){ 203 204 if(FD_ISSET(i, ¤t_rdfs)){ 205 if(listenfd == i){ 206 if((sockfd = accept(listenfd, (struct sockaddr*)&client, &cli_len))<0){ 207 perror("accept error.\n"); 208 return -1; 209 } 210 FD_CLR(i, ¤t_rdfs); 211 maxfd = maxfd > sockfd ? maxfd :sockfd; 212 FD_SET(sockfd, &global_rdfs); 213 } 214 else{ 215 bzero(buffer,BUFFER_SIZE); 216 bytes = recv(i, buffer, BUFFER_SIZE, 0); 217 if(bytes < 0){ 218 perror("recv error.\n"); 219 return -1; 220 } 221 if(bytes == 0){ 222 FD_CLR(i, &global_rdfs); 223 close(i); 224 continue; 225 } 226 printf("收到的buf:%s\n", buffer); 227 // send(i, buffer, strlen(buffer), 0); 228 if(get(buffer)){ //索引判断是否存在 229 printf("Result -- %s !\n",get(buffer)); 230 printf("----------------------------------------------\n"); 231 if(send(i,buffer,BUFFER_SIZE,0)<0){ 232 printf("Server Send Failed\n"); 233 break; 234 } 235 continue; 236 } 237 else{ 238 flag = devide(buffer,0); //进行分词 239 if(flag){ 240 char output[BUFFER_SIZE]; 241 bzero(output,BUFFER_SIZE); 242 printf("Result -- "); 243 for(z=0;z<k-1;z++){ 244 printf("%s",search[z]); 245 strcat(output,search[z]); //拼接 指针数组送不过去 246 } 247 out_length = strlen(output); 248 printf("\n"); 249 printf("----------------------------------------------\n"); 250 if(send(i,output,out_length,0)<0){ 251 printf("Server Send Failed\n"); 252 break; 253 } 254 } 255 else{ 256 printf("No Search ! \n"); 257 printf("----------------------------------------------\n"); 258 char no[BUFFER_SIZE]; 259 bzero(no,BUFFER_SIZE); 260 strcat(no,"No Find ! "); 261 int no_find_length = sizeof(no); 262 if(send(i,no,no_find_length,0)<0) 263 { 264 printf("Server Send Failed\n"); 265 break; 266 } 267 } 268 } 269 } 270 271 } 272 273 } 274 } 275 close(listenfd); 276 return 0; 277 278 }
以上是自己花了一段时间写的测试程序,学习了ruby的hash,以及用linux-c写的socket通讯,发现还蛮好玩的,继续努力。
第一次写博客,排版可能有点丑。