Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #define MAX_STR_COUNT 10000
- #define MAX_STR_LEN 100000
- typedef struct {
- void* prev;
- void* next;
- unsigned long long prefix_hash;
- unsigned long long all_string_hash;
- void** all_prefixes_hashes;
- int hashes_count;
- } node;
- node* hashtable[MAX_STR_COUNT];
- unsigned long long str_hash(const char* str, int Len);
- void _insert(char* str_data,int Len);
- void _delete(char* str_data,int Len);
- void _prefix(char* str_data,int Len);
- int main(int argc,char** argv){
- int N,i;
- memset(hashtable,0,MAX_STR_COUNT*sizeof(node*));
- scanf("%d",&N);
- for (i=0;i!=N;i++){
- char command[10];
- memset(command,0,10);
- scanf("%s",command);
- if (command[0]=='I'){
- char str_data[MAX_STR_LEN];
- int Len;
- //memset(str_data,0,MAX_STR_LEN);
- scanf("%s",str_data);
- Len = strlen(str_data);
- _insert(str_data,Len);
- }
- if (command[0]=='D'){
- char str_data[MAX_STR_LEN];
- int Len;
- //memset(str_data,0,MAX_STR_LEN);
- scanf("%s",str_data);
- Len = strlen(str_data);
- _delete(str_data,Len);
- }
- if (command[0]=='P'){
- char str_data[MAX_STR_LEN];
- int Len;
- //memset(str_data,0,MAX_STR_LEN);
- scanf("%s",str_data);
- Len = strlen(str_data);
- _prefix(str_data,Len);
- }
- }
- for (i=0;i!=MAX_STR_COUNT;i++){
- node* head = hashtable[i];
- while(head != 0){
- node* next = (node*)head->next;
- if (head->all_prefixes_hashes!=0)
- free(head->all_prefixes_hashes);
- free (head);
- head = next;
- }
- }
- return 0;
- }
- unsigned long long str_hash(const char* str, int Len){
- const int p = 31;
- unsigned long long hash = 0, p_pow = 1;
- int i;
- for (i=0; i<Len; ++i)
- {
- hash += (str[i] - 'a' + 1) * p_pow;
- p_pow *= p;
- }
- return hash;
- }
- void _insert(char* str_data,int Len){
- int k;
- unsigned long long string_hash;
- node* head_node = 0;
- node* cashe2_node = 0;
- int wf = 0;
- int h1;
- const int p = 31;
- unsigned long long prefix_hash = 0, p_pow = 1;
- node **prefixes_nodes_array = 0;
- int p_array_index = 0;
- string_hash = str_hash(str_data,Len);
- //ищем такой хэш
- h1 = string_hash % MAX_STR_COUNT;
- head_node = hashtable[h1];
- while (head_node != 0){
- if (head_node->all_string_hash == string_hash)
- return ;
- head_node = (node*)head_node->next;
- }
- prefixes_nodes_array = (node*)malloc(Len * sizeof(node*));
- //считаем хэш от всех префиксов
- for (k=0;k!=Len;k++){
- int h1;
- node* head;
- node* new_node;
- prefix_hash += (str_data[k] - 'a' + 1) * p_pow;
- p_pow *= p;
- h1 = prefix_hash % MAX_STR_COUNT;
- head = hashtable[h1];
- new_node = (node*)malloc(sizeof(node));
- new_node->prev = 0;
- new_node->next = head;
- if (head!=0)
- head->prev = new_node;
- new_node->all_string_hash = string_hash;
- new_node->prefix_hash = prefix_hash;
- new_node->all_prefixes_hashes = 0;
- new_node->hashes_count = 0;
- hashtable[h1] = new_node;
- prefixes_nodes_array[p_array_index] = new_node;
- p_array_index++;
- //в последний элемент добавляем массив, в котором храним все кэши
- if (prefix_hash==string_hash){
- new_node->all_prefixes_hashes = prefixes_nodes_array;
- new_node->hashes_count = Len;
- }
- }
- }
- void _delete(char* str_data,int Len){
- int k;
- unsigned long long string_hash;
- node* head_node = 0;
- int wf = 0;
- const int p = 31;
- unsigned long long prefix_hash = 0, p_pow = 1;
- int h1;
- node** nodes = 0;
- int nodes_count = 0;
- string_hash = str_hash(str_data,Len);
- //ищем последний элемент в списке префиксов
- h1 = string_hash % MAX_STR_COUNT;
- head_node = hashtable[h1];
- while(head_node!=0){
- if ((head_node->all_string_hash==string_hash)&&(head_node->prefix_hash==string_hash)){
- nodes = head_node->all_prefixes_hashes;
- nodes_count = head_node->hashes_count;
- break;
- }
- head_node = (node*)head_node->next;
- }
- if (nodes==0)
- return ;
- for (k=0;k!=nodes_count;k++){
- node* head = nodes[k];
- if (head->prev==0){
- //это первый элемент в списке
- h1 = head->prefix_hash % MAX_STR_COUNT;
- hashtable[h1] = head->next;
- } else{
- node* prev_node = (node*)head->prev;
- prev_node->next = head->next;
- }
- if (head->next != 0){
- node* next_node = (node*)head->next;
- next_node->prev = head->prev;
- }
- free(head);
- }
- free(nodes);
- /*
- //считаем хэш от всех префиксов
- for (k=0;k!=Len;k++){
- int h1;
- node* head;
- prefix_hash += (str_data[k] - 'a' + 1) * p_pow;
- p_pow *= p;
- h1 = prefix_hash % MAX_STR_COUNT;
- head = hashtable[h1];
- while(head != 0){
- if ((head->all_string_hash==string_hash)&&(head->prefix_hash==prefix_hash)){
- //удаляем head
- if (head->prev==0){
- //это первый элемент в списке
- hashtable[h1] = head->next;
- } else{
- node* prev_node = (node*)head->prev;
- prev_node->next = head->next;
- }
- if (head->next != 0){
- node* next_node = (node*)head->next;
- next_node->prev = head->prev;
- }
- free(head);
- break;
- }
- head = (node*)head->next;
- }
- }
- */
- }
- void _prefix(char* str_data,int Len){
- unsigned long long string_hash;
- node* head = 0;
- int wf = 0;
- int h1;
- int Count = 0;
- string_hash = str_hash(str_data,Len);
- h1 = string_hash % MAX_STR_COUNT;
- head = hashtable[h1];
- while(head != 0){
- if (head->prefix_hash==string_hash)
- Count++;
- head = (node*)head->next;
- }
- printf("%d\n",Count);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement