基于C/S架构的Trie树查询

一 问题

    模拟一个成绩查询系统,用户输入姓名,返回相应的分数,整个查询过程放在服务器上运行,采用Trie树加速查询。

二 代码

服务器端:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <netinet/in.h>
#include <ctype.h>

#define N 8
typedef const char * keyType;
typedef unsigned int valType;
/*
 * to define a Person structure and initialize
 * */
typedef struct Person {
    keyType name;
    valType score;
}Person;
Person person[N] = {{"LiTao", 89}, {"ZhangQiang", 77},  {"ChengTianXiong", 88}, {"ZhangWei", 90},
    {"SongTao", 100}, {"LiMin", 88}, {"SongZuDe", 88}, {"ChengFei", 66}};
/*
 * to define Trie node structure
 * */
enum NodeType {UNCOMPLETED, COMPLETED};
typedef struct TrieNode {
    enum NodeType type;
    char ch;
    valType val;
    struct TrieNode *child[26];
}TrieNode;
TrieNode *root;  // the root of trie 
/*
 * to define some functions for Trie 
 * */
TrieNode * newTrieNode(char ch) {
    TrieNode *p =(TrieNode *)malloc(sizeof(TrieNode));
    if(!p) {
	perror("Memory error!\n");
	exit(1);
    }
    p->type = UNCOMPLETED;
    p->ch = ch;
//  memset(p->child, NULL, sizeof(p->child)); // there are some warnings if using memset 
    int i;
    for(i = 0;i < 26;i++) p->child[i] = NULL;

    return p;
}
int index(char ch) {
    if(isupper(ch)) ch = tolower(ch);
    return ch - 'a';
}
void createTrieroot() {
    root = newTrieNode('@');
}
void insertNode(keyType key, valType val) {
    TrieNode *ptr = root;
    int pos;
    int i;
    for(i = 0;key[i];i++) {
	pos = index(key[i]);
	if(ptr->child[pos] == NULL) {
	    ptr->child[pos] = newTrieNode(key[i]);
	}
	ptr = ptr->child[pos];
    }
    ptr->type = COMPLETED;
    ptr->val = val;
}
/*
 * to find the val in terms of key 
 * return -1 if fail to find 
 * */
int find(keyType key) {
    TrieNode *ptr = root;
    int pos;
    int i;
    for(i = 0;key[i];i++) {
	pos = index(key[i]);
	if(ptr->child[pos] == NULL) break;
	ptr = ptr->child[pos];
    }
    if(!key[i] && ptr->type == COMPLETED) return ptr->val;
    else return -1;
}
void createTrie() {
    if(root) return;
    createTrieroot();
    int i;
    keyType key;
    valType val;
    for(i = 0;i < N;i++) {
	key = person[i].name;
	val = person[i].score;
	if(find(key) == -1) {
	    insertNode(key, val);
	}
    }
}
int main() {
    createTrie();
    /*
     * to test some cases
     * */
//  char name[20];
//  while(1) {
//	  gets(name);
//        int val = find(name);
//        printf("%d\n", val);
//}
    /*
     * the socket fd is same the file descriptor
     * */
    int server_sockfd = -1;
    int client_sockfd = -1;
    int client_len = 0;
    /*
     * to define socket address
     * */
    struct sockaddr_in server_addr;
    struct sockaddr_in client_addr;
    /*
     * to create a socket 
     * a socket contains domain, type and protocal
     * */
    server_sockfd = socket(AF_INET, SOCK_STREAM, 0);
//  bzero(&server_addr, sizeof(server_addr));  // to clear the server_addr
    /*
     * to initialize the socket address 
     * */
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
    /*
     * pay attention
     * the port should be same with the port from client 
     * */
    server_addr.sin_port = htons(9736);
    /*
     * to bind the sockect and its address 
     * */
    bind(server_sockfd, (struct sockaddr *)&server_addr, sizeof(server_addr));
    /*
     * to listen the port 
     * */
    listen(server_sockfd, 5);
    /*
     * to ignore child processes which stop 
     * */
   signal(SIGCHLD, SIG_IGN);
    
    while(1) {
	keyType key;
        valType val = -1;

	client_len = sizeof(client_addr);
	printf("server is waiting...\n");
	/*
	 * to accept a connect from a client socket 
	 * */
	client_sockfd = accept(server_sockfd, (struct sockaddr *)&client_addr, &client_len);
        /*
	 * let the child process to deal with 
	 * */
	if(fork() == 0) {
	    /*
	     * read data from socket 
	     * */
	    char name[20];
	    read(client_sockfd, &name, sizeof(name));
	    int  score = find(name);     // to search in the trie 
	    /*
	     * write the data to socket 
	     * */
	    write(client_sockfd, &score, sizeof(score));
	    close(client_sockfd);
	    exit(0);
	}
	else {
	    close(client_sockfd);
	}
    }
    close(server_sockfd);
    return 0;
}

客户端:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int main() {
    /*
     * the socket fd is same the file descriptor
     * */
    int sockfd = -1;
    int len = 0;
    /*
     * to define socket address
     * */
    struct sockaddr_in address;
    int result;

    char name[20];
    unsigned int score;

    int i;
    for(i = 0;i < 10;i++) {
    /*
     * to create a socket 
     * a socket contains domain, type and protocal
     * */
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    /*
     * to initialize the socket address 
     * */
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(9736);
    len = sizeof(address);
    /*
     * to connect the server 
     * */
    result = connect(sockfd, (struct sockaddr *)&address, len);
    if(result == -1) {
	perror("ops:client!\n");
	exit(1);
    }

    printf("input a name:");
    gets(name);
    write(sockfd, &name, sizeof(name));
    read(sockfd, &score, sizeof(score));
    printf("score from server = %d\n", score);

    close(sockfd);
    }
    exit(0);

    return 0;
}

三 测试

基于C/S架构的Trie树查询_第1张图片

基于C/S架构的Trie树查询_第2张图片

四 分析

服务器

基于C/S架构的Trie树查询_第3张图片

你可能感兴趣的:(基于C/S架构的Trie树查询)