Advertisement
Ladies_Man

#ARCH_2 Compact_Trie

Oct 11th, 2014
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.18 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <time.h>
  5.  
  6. #define VERTS_COUNT 2
  7.  
  8. typedef struct{
  9.         char *value;
  10.         char* leaf;
  11.         struct vertex *parent;
  12.         struct vertex *arcs[VERTS_COUNT];
  13.         int arcs_count;
  14. } vertex;
  15.  
  16. void init_vertex(vertex* v){
  17.         v->value = 0;
  18.         v->leaf = 0;
  19.         v->parent = 0;
  20.         memset(v->arcs,0,sizeof(vertex*) * VERTS_COUNT);
  21.         v->arcs_count = 0;
  22. }
  23.  
  24. vertex* malloc_and_init_vertex(){
  25.         vertex* v = (vertex*)malloc(sizeof(vertex));
  26.         init_vertex(v);
  27.         return v;
  28. }
  29.  
  30. //считает длину совпадающего префикса в двух строках
  31. int get_identical_symbols_count(char* s1,char* s2){
  32.         int c_count = 0;
  33.         char* s1_p = s1;
  34.         char* s2_p = s2;
  35.         while(s1_p[0] && s2_p[0]){
  36.                 if (s1_p[0] != s2_p[0]) break;
  37.                 c_count++;
  38.                 s1_p++;
  39.                 s2_p++;
  40.         }
  41.         return c_count;
  42. }
  43.  
  44. //разворачивает leaf узла дерева в цепочку потомков
  45. vertex* expand_leaf_and_ret_child(vertex* head_v, int syms_count){
  46.         vertex* cv = head_v;
  47.         int i;
  48.         for (i = 0; i != syms_count; i++){
  49.                 char c = head_v->leaf[i];
  50.                 int index = c - '0';
  51.                 //создаем новую вершину
  52.                 vertex* new_v = malloc_and_init_vertex();
  53.                 new_v->parent = cv;
  54.                 cv->arcs_count++;
  55.                 cv->arcs[index] = new_v;
  56.                 cv = new_v;
  57.         }
  58.  
  59.         //сохраняем остаток leaf в cv
  60.         if (strlen(head_v->leaf) > syms_count) cv->leaf = strdup(head_v->leaf + syms_count);
  61.         //free (head_v->leaf);
  62.         head_v->leaf = 0;
  63.         if (head_v->value){
  64.                 //переносим значение в конец цепочки
  65.                 cv->value = head_v->value;
  66.                 head_v->value = 0;
  67.         }
  68.         return cv;
  69. }
  70. //вставка ключа
  71. void insert_key(vertex* head_v, char* key, char* value){
  72.         vertex* current_vertex = head_v;
  73.         char* current_key = key;
  74.  
  75.         while (strlen(current_key)){
  76.                 char c = current_key[0];
  77.                 int index = c - '0';
  78.                 vertex* nv = current_vertex->arcs[index];
  79.                 if (!nv){
  80.                         //такой дуги еще нет.
  81.                         //прежде чем ее создавать - проверяем leaf
  82.                         if (current_vertex->leaf != 0){
  83.                                 if (strcmp(current_vertex->leaf,current_key)==0){
  84.                                         //нашли ключ. заменяем значение
  85.                                         //if (current_vertex->value) free (current_vertex->value);
  86.                                         current_vertex->value = strdup(value);//создает строку value и возвр указатель на нее
  87.                                         return ;
  88.                                 }
  89.                                 //leaf не пустой. проверяем - сколько первых символов совпадают в leaf и current_key
  90.                                 int eq_syms_count = get_identical_symbols_count(current_vertex->leaf,current_key);
  91.                                 if (eq_syms_count>0){
  92.                                         //надо распределить первые символы leaf, создать новый элемент и перейти в него
  93.                                         vertex* arc_v = expand_leaf_and_ret_child(current_vertex,eq_syms_count);
  94.                                         current_key += eq_syms_count;
  95.                                         current_vertex = arc_v;
  96.  
  97.                                 } else{
  98.                                         //в leaf и current_key первые символы разные
  99.                                         //оставляем leaf как есть, создаем новый элемент, переходим в него
  100.                                         vertex* arc_v = malloc_and_init_vertex();
  101.                                         arc_v->parent = current_vertex;
  102.                                         current_vertex->arcs[index] = arc_v;
  103.                                         current_vertex->arcs_count++;
  104.                                         current_key++;
  105.                                         current_vertex = arc_v;
  106.                                 }
  107.                         } else{
  108.                                 //leaf пустой. смотрим значение
  109.                                 if (!current_vertex->value){
  110.                                         //значения нет.
  111.                                         //сохраняем key -> leaf
  112.                                         current_vertex->leaf = strdup(current_key);
  113.                                         //value -> current_vertex->value
  114.                                         current_vertex->value = strdup(value);
  115.                                         return ;
  116.                                 } else{
  117.                                         //уже есть значение
  118.                                         //создаем потомка
  119.                                         vertex* arc_v = malloc_and_init_vertex();
  120.                                         arc_v->parent = current_vertex;
  121.                                         current_vertex->arcs[index] = arc_v;
  122.                                         current_vertex->arcs_count++;
  123.                                         current_vertex = arc_v;
  124.                                         current_key++;
  125.                                 }
  126.                         }
  127.                 } else{
  128.                         //такая дуга уже есть. переходим в нее
  129.                         current_key++;
  130.                         current_vertex = nv;
  131.                 }
  132.         }
  133.         //полностью перебрали ключ, нашли последнюю вершину
  134.         if (current_vertex){
  135.                 //у него может быть leaf
  136.                 //убираем leaf в дугу
  137.                 if (current_vertex->leaf) {vertex* v1 = expand_leaf_and_ret_child(current_vertex,1);};
  138.                 //if (current_vertex->value) free(current_vertex->value);
  139.                 current_vertex->value = strdup(value);
  140.         }
  141. }
  142. //спуск по дереву до определенного ключа
  143. vertex* descent_to(vertex* head_v, char* key){
  144.         vertex* cv = head_v;
  145.         char* current_key = key;
  146.         while (strlen(current_key) > 0){
  147.                 //есть leaf?
  148.                 if (cv->leaf)
  149.                         //leaf совпадает с ключем
  150.                         if (strcmp(cv->leaf,current_key)==0) break;
  151.                         char c = current_key[0];
  152.                         int index = c - '0';
  153.                         vertex* v = cv->arcs[index];
  154.                         if (!v) return 0;// такой дуги нет
  155.                         //такая дуга есть, переходим в нее
  156.                         current_key++;
  157.                         cv = v;
  158.         }
  159.         //дошли до конца
  160.         return cv;
  161. }
  162.  
  163. char* lookup_key(vertex* head_v, char* key){
  164.         vertex* v = descent_to(head_v,key);
  165.         char* ret_value = 0;
  166.         if (v) ret_value = v->value;
  167.         return ret_value;
  168. }
  169.  
  170. int delete_key(vertex* head_v, char* key){
  171.         int e_count = 0;
  172.  
  173.         vertex* v = descent_to(head_v,key);
  174.         if (!v) return 0;
  175.         //весь ключ в leaf
  176.         if (v->leaf){
  177.                 //free (v->leaf);
  178.                 v->leaf = 0;
  179.         }
  180.         if (v->value){
  181.                 //free (v->value);
  182.                 v->value = 0;
  183.         }
  184.         //если узел не конечный - выходим
  185.         if (v->arcs_count) return 0;
  186.         //надо удалять узел и двигаться вверх по дереву
  187.         do{
  188.                 vertex* parent_v = v->parent;
  189.                 int i;
  190.                 if (!parent_v) break;
  191.                 for (i = 0; i != VERTS_COUNT; i++)
  192.                         if (parent_v->arcs[i] == v){
  193.                                 parent_v->arcs[i] = 0;
  194.                                 parent_v->arcs_count--;
  195.                                 //if (v->value) free (v->value);
  196.                                 //free (v);
  197.                                 e_count ++;
  198.                                 //узел удалили, начинаем проверять родителя
  199.                                 v = parent_v;
  200.                                 break;
  201.                         }
  202.                 //если поднялись на самый верх - выходим
  203.                 if (!v) break;
  204.         }
  205.         while ((v->arcs_count==0)&&(v->leaf==0)&&(v->value==0));
  206.  
  207.         return e_count;
  208. }
  209.  
  210. #define SIZE 22000
  211. #define AVG_LEN 80
  212.  
  213. int main(int argc,char** argv){
  214.         vertex head_vertex;
  215.         init_vertex(&head_vertex);
  216.  
  217.         int i, j, n;
  218.         char word_arr[SIZE][AVG_LEN+1];
  219.         double time1, time4;
  220.  
  221.         FILE *fp = fopen("test_80_200k_bin_firstsame_3qtrs.txt", "r");
  222.         if (NULL == fp) printf("cannot open file\n");
  223.         FILE *ff = fopen("test_80_200k_bin_firstsame_3qtrs_RESULT.csv", "w");
  224.     //"test_5_200k_bin.txt"
  225.     //"test_40_200k_bin.txt"
  226.     //"test_40_200k_bin_firstsame.txt"
  227.     //"test_80_200k_bin_first34same.txt"
  228.  
  229.         for (i = 0; i < SIZE; i++) fscanf(fp, "%s\n", word_arr[i]);
  230.  
  231.         fprintf(ff, "Num of keys;Time");
  232.         for (j = 0; j <= SIZE; j+=2000) {
  233.             time1 = clock();
  234.             for (i = 0; i < j; i++) insert_key(&head_vertex, word_arr[i], "");
  235.             time4 = clock() - time1;
  236.             fprintf(ff, "%d;=%.3G\n", j, time4);
  237.         }
  238.  
  239.  
  240.         printf("Compact\n");
  241.         printf("i=%d\n", i);
  242.         printf("time4=%.2lf\n", time4);
  243.  
  244.         fclose(fp);
  245.         fclose(ff);
  246. /*
  247.         char command[10], key[1000], value[1000];
  248.         scanf("%d", &n);                        //num of commands
  249.         for (i = 0; i < n; i++) {
  250.                 scanf("%s", command);
  251.                 if ('i' == command[0]) {        //insert
  252.                         scanf("%s%s", key, value);
  253.                         insert_key(&head_vertex,key, value);
  254.                 }
  255.                 if ('d' == command[0]) {        //delete
  256.                         int d_count = 0;
  257.                         scanf("%s", key);
  258.                         d_count = delete_key(&head_vertex,key);
  259.                         printf("deleted %d nodes\n",d_count);
  260.                 }
  261.                 if ('l' == command[0]) {        //lookup
  262.                         scanf("%s", key);
  263.                         char *value;
  264.                         value = lookup_key(&head_vertex,key);
  265.                         if (value) printf("%s\n",value);
  266.                 }
  267.         }*/
  268.         return 0;
  269. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement