Advertisement
Ladies_Man

Prefix trie (not a trie here) (строки с общими префиксами)

Dec 30th, 2013
141
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 5.81 KB | None | 0 0
  1. #include <stdio.h>
  2.  
  3. #define MAX_STR_COUNT 10000
  4. #define MAX_STR_LEN 100000
  5.  
  6. typedef struct {
  7.         void* prev;
  8.     void* next;
  9.  
  10.     unsigned long long prefix_hash;
  11.     unsigned long long all_string_hash;
  12.  
  13.     void** all_prefixes_hashes;
  14.     int hashes_count;
  15. } node;
  16.  
  17. node* hashtable[MAX_STR_COUNT];
  18.  
  19. unsigned long long str_hash(const char* str, int Len);
  20.  
  21. void _insert(char* str_data,int Len);
  22. void _delete(char* str_data,int Len);
  23. void _prefix(char* str_data,int Len);
  24.  
  25. int main(int argc,char** argv){
  26.     int N,i;
  27.  
  28.     memset(hashtable,0,MAX_STR_COUNT*sizeof(node*));
  29.    
  30.  
  31.     scanf("%d",&N);
  32.     for (i=0;i!=N;i++){
  33.         char command[10];
  34.  
  35.         memset(command,0,10);
  36.  
  37.         scanf("%s",command);
  38.  
  39.         if (command[0]=='I'){
  40.             char str_data[MAX_STR_LEN];
  41.             int Len;
  42.  
  43.             //memset(str_data,0,MAX_STR_LEN);
  44.             scanf("%s",str_data);
  45.             Len = strlen(str_data);
  46.             _insert(str_data,Len);
  47.         }
  48.        
  49.         if (command[0]=='D'){
  50.                 char str_data[MAX_STR_LEN];
  51.                 int Len;
  52.  
  53.                 //memset(str_data,0,MAX_STR_LEN);
  54.                 scanf("%s",str_data);
  55.                 Len = strlen(str_data);
  56.  
  57.                 _delete(str_data,Len);
  58.             }
  59.  
  60.         if (command[0]=='P'){
  61.                 char str_data[MAX_STR_LEN];
  62.                 int Len;
  63.                
  64.                 //memset(str_data,0,MAX_STR_LEN);
  65.                 scanf("%s",str_data);
  66.                 Len = strlen(str_data);
  67.  
  68.                 _prefix(str_data,Len);
  69.         }
  70.     }
  71.  
  72.     for (i=0;i!=MAX_STR_COUNT;i++){
  73.         node* head = hashtable[i];
  74.         while(head != 0){
  75.             node* next = (node*)head->next;
  76.  
  77.            
  78.             if (head->all_prefixes_hashes!=0)
  79.                 free(head->all_prefixes_hashes);
  80.            
  81.             free (head);
  82.             head = next;
  83.         }
  84.     }
  85.     return 0;
  86. }
  87.  
  88. unsigned long long str_hash(const char* str, int Len){
  89.     const int p = 31;
  90.     unsigned long long hash = 0, p_pow = 1;
  91.     int i;
  92.  
  93.     for (i=0; i<Len; ++i)
  94.     {
  95.         hash += (str[i] - 'a' + 1) * p_pow;
  96.         p_pow *= p;
  97.     }
  98.     return hash;
  99. }
  100.  
  101.  
  102. void _insert(char* str_data,int Len){
  103.  
  104.     int k;
  105.     unsigned long long string_hash;
  106.     node* head_node = 0;
  107.     node* cashe2_node = 0;
  108.     int wf = 0;
  109.     int h1;
  110.  
  111.     const int p = 31;
  112.     unsigned long long prefix_hash = 0, p_pow = 1;
  113.  
  114.     node **prefixes_nodes_array = 0;
  115.     int p_array_index = 0;
  116.  
  117.  
  118.     string_hash = str_hash(str_data,Len);
  119.     //ищем такой хэш
  120.     h1 = string_hash % MAX_STR_COUNT;
  121.     head_node = hashtable[h1];
  122.     while (head_node != 0){
  123.         if (head_node->all_string_hash == string_hash)
  124.             return ;
  125.         head_node = (node*)head_node->next;
  126.     }
  127.  
  128.     prefixes_nodes_array = (node*)malloc(Len * sizeof(node*));
  129.  
  130.     //считаем хэш от всех префиксов
  131.     for (k=0;k!=Len;k++){
  132.         int h1;
  133.         node* head;
  134.         node* new_node;
  135.  
  136.         prefix_hash += (str_data[k] - 'a' + 1) * p_pow;
  137.         p_pow *= p;
  138.  
  139.         h1 = prefix_hash % MAX_STR_COUNT;
  140.         head = hashtable[h1];
  141.  
  142.         new_node = (node*)malloc(sizeof(node));
  143.         new_node->prev = 0;
  144.         new_node->next = head;
  145.  
  146.         if (head!=0)
  147.             head->prev = new_node;
  148.  
  149.         new_node->all_string_hash = string_hash;
  150.         new_node->prefix_hash = prefix_hash;
  151.  
  152.         new_node->all_prefixes_hashes = 0;
  153.         new_node->hashes_count = 0;
  154.  
  155.         hashtable[h1] = new_node;
  156.  
  157.         prefixes_nodes_array[p_array_index] = new_node;
  158.         p_array_index++;
  159.  
  160.         //в последний элемент добавляем массив, в котором храним все кэши
  161.        
  162.         if (prefix_hash==string_hash){
  163.             new_node->all_prefixes_hashes = prefixes_nodes_array;
  164.             new_node->hashes_count = Len;
  165.         }
  166.     }
  167. }
  168.  
  169. void _delete(char* str_data,int Len){
  170.                 int k;
  171.                 unsigned long long string_hash;
  172.                 node* head_node = 0;
  173.                 int wf = 0;
  174.                 const int p = 31;
  175.                 unsigned long long prefix_hash = 0, p_pow = 1;
  176.                 int h1;
  177.                 node** nodes = 0;
  178.                 int nodes_count = 0;
  179.                 string_hash = str_hash(str_data,Len);
  180.  
  181.                 //ищем последний элемент в списке префиксов
  182.                 h1 = string_hash % MAX_STR_COUNT;
  183.                 head_node = hashtable[h1];
  184.                 while(head_node!=0){
  185.                     if ((head_node->all_string_hash==string_hash)&&(head_node->prefix_hash==string_hash)){
  186.                         nodes = head_node->all_prefixes_hashes;
  187.                         nodes_count = head_node->hashes_count;
  188.                         break;
  189.                     }
  190.  
  191.                     head_node = (node*)head_node->next;
  192.                 }
  193.                 if (nodes==0)
  194.                     return ;
  195.  
  196.                 for (k=0;k!=nodes_count;k++){
  197.                     node* head = nodes[k];
  198.                     if (head->prev==0){
  199.                         //это первый элемент в списке
  200.                         h1 = head->prefix_hash % MAX_STR_COUNT;
  201.                         hashtable[h1] = head->next;
  202.                     } else{
  203.                         node* prev_node = (node*)head->prev;
  204.                         prev_node->next = head->next;
  205.                     }
  206.  
  207.                     if (head->next != 0){
  208.                         node* next_node = (node*)head->next;
  209.                         next_node->prev = head->prev;
  210.                     }
  211.                     free(head);
  212.                 }
  213.  
  214.                 free(nodes);
  215.                
  216.                 /*
  217.                 //считаем хэш от всех префиксов
  218.                 for (k=0;k!=Len;k++){
  219.                    
  220.                     int h1;
  221.                     node* head;
  222.  
  223.                     prefix_hash += (str_data[k] - 'a' + 1) * p_pow;
  224.                     p_pow *= p;
  225.  
  226.  
  227.                     h1 = prefix_hash % MAX_STR_COUNT;
  228.                     head = hashtable[h1];
  229.  
  230.                     while(head != 0){
  231.                         if ((head->all_string_hash==string_hash)&&(head->prefix_hash==prefix_hash)){
  232.                             //удаляем head
  233.                             if (head->prev==0){
  234.                                 //это первый элемент в списке
  235.                                 hashtable[h1] = head->next;
  236.                             } else{
  237.                                 node* prev_node = (node*)head->prev;
  238.                                 prev_node->next = head->next;
  239.                             }
  240.  
  241.                             if (head->next != 0){
  242.                                 node* next_node = (node*)head->next;
  243.                                 next_node->prev = head->prev;
  244.                             }
  245.                             free(head);
  246.                             break;
  247.                         }
  248.  
  249.                         head = (node*)head->next;
  250.                     }
  251.                 }
  252.                 */
  253.                
  254. }
  255. void _prefix(char* str_data,int Len){
  256.  
  257.     unsigned long long string_hash;
  258.     node* head = 0;
  259.     int wf = 0;
  260.     int h1;
  261.     int Count = 0;
  262.  
  263.  
  264.     string_hash = str_hash(str_data,Len);
  265.     h1 = string_hash % MAX_STR_COUNT;
  266.  
  267.     head = hashtable[h1];
  268.  
  269.     while(head != 0){
  270.  
  271.         if (head->prefix_hash==string_hash)
  272.             Count++;
  273.  
  274.         head = (node*)head->next;
  275.     }
  276.  
  277.     printf("%d\n",Count);
  278. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement