Cod sursa(job #1045015)

Utilizator TheShadowsAlexandru Cristian TheShadows Data 30 noiembrie 2013 19:16:25
Problema Trie Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.89 kb
#include<cstdio>
#include<cstring>
using namespace std;
const int LIMARG = 21;
FILE *in=fopen("trie.in","r"), *out=fopen("trie.out","w");
struct node;
struct vertex{
    node *to=NULL;
    vertex *next=NULL;
};
struct node{
    int cnt=0;
    char ch=0;
    vertex *links=NULL;
}sentinel;
void addString(char arg[]){
    int n=0, sz=strlen(arg);
    vertex *vtx;
    node *current=&sentinel;
    if(sentinel.links==NULL){
        /*
            if the sentinel is empty, put the
            first letter in and increase n
        */
        sentinel.links = new vertex;
        sentinel.links->to = new node;
        sentinel.links->to->ch = arg[n];
        current = sentinel.links->to;
        n++;
    }
    while(n<sz){
        if(current->links==NULL){
            current->links = new vertex;
            current->links->to = new node;
            current->links->to->ch = arg[n];
            current = current->links->to;
        }else{
            vtx = current->links;
            while(vtx->next!=NULL&&vtx->to->ch!=arg[n]){
                vtx=vtx->next;
            }
            if(vtx->to->ch==arg[n]){
                current=vtx->to;
            }else{
                vtx->next = new vertex;
                vtx = vtx->next;
                vtx->to = new node;
                vtx->to->ch = arg[n];
                current = vtx->to;
            }
        }
        n++;
    }

    current->cnt++;
}
node* findString(char arg[]){
    if(sentinel.links==NULL){
        return NULL;
    }
    node *current=&sentinel; vertex *vtx;
    int n=0, sz=strlen(arg);
    while(n<sz){
        if(current->links==NULL){
            return NULL;
        }else{
            vtx = current->links;
            while(vtx->next!=NULL&&vtx->to->ch!=arg[n]){
                vtx = vtx->next;
            }
            if(vtx->to->ch==arg[n]){
                current=vtx->to;
            }else{
                return NULL;
            }
        }
        n++;
    }
    if(current->cnt==0)
        return NULL;
    return current;
}
int maxPrefix(char arg[]){
    if(sentinel.links==NULL){
        return 0;
    }
    node *current=&sentinel; vertex *vtx;
    int n=0, sz=strlen(arg);
    while(n<sz){
        if(current->links==NULL){
            return n;
        }else{
            vtx = current->links;
            while(vtx->next!=NULL&&vtx->to->ch!=arg[n]){
                vtx = vtx->next;
            }
            if(vtx->to->ch==arg[n]){
                current=vtx->to;
            }else{
                return n;
            }
        }
        n++;
    }
    return n;
}
void freeMemory(node *current){
    vertex *vtx = current->links;
    while(vtx!=NULL){
        freeMemory(vtx->to);
        vtx = vtx->next;
    }
    delete current;
}
void deleteString(char arg[]){
    if(sentinel.links==NULL){
        printf("Deletion error");
        return;
    }
    node *current=&sentinel, *lastNode=&sentinel;
    char lastFound=arg[0];
    vertex *vtx;
    int n=0, sz=strlen(arg);
    while(n<sz){
        if(current->links==NULL){
            printf("Deletion error");
            return;
        }else{
            vtx = current->links;
            while(vtx->next!=NULL&&vtx->to->ch!=arg[n]){
                vtx = vtx->next;
            }
            if(vtx->to->ch==arg[n]){
                if(current->links->next!=NULL||(current->cnt>0&&n<sz)){
                    lastNode=current;
                    lastFound=arg[n];
                }
                current=vtx->to;
            }else{
                printf("Deletion error");
                return;
            }
        }
        n++;
    }


    if(current->cnt>1||current->links!=NULL){
        current->cnt--;
        return;
    }
    current=lastNode;
    vtx = current->links;
    if(vtx->to->ch==lastFound){
        freeMemory(vtx->to);
        current->links=vtx->next;
        delete vtx;
    }else{
        while(vtx->next!=NULL&&vtx->next->to->ch!=lastFound){
            vtx = vtx->next;
        }
        freeMemory(vtx->next->to);
        vertex *aux = vtx->next;
        vtx->next=vtx->next->next;
        delete aux;
    }

}
int main(){
    char arg[LIMARG]; int oper;
    while(!feof(in)){
        fscanf(in, "%d%s\n", &oper, &arg);
        if(oper==0){
            node *n = findString(arg);
            if(n==NULL){
                addString(arg);
            }else{
                n->cnt++;
            }
        }else if(oper==1){
            deleteString(arg);
        }else if(oper==2){
            node *n = findString(arg);
            if(n == NULL){
                fprintf(out, "0\n");
            }else{
                fprintf(out, "%d\n", n->cnt);
            }
        }else if(oper==3){
            int res = maxPrefix(arg);
            fprintf(out, "%d\n", res);
        }

    }
    return 0;
}