Progetto di informatica

di il
73 risposte

73 Risposte - Pagina 4

  • Re: Progetto di informatica

    Premesso che

    - non sono andato a riguardarmi il codice che ho scritto in passato;
    - l'argomento “file I/O” mi mancava e ho appena letto velocemente qualcosina al riguardo;
    - il mio PC è un rottame;

    questo

         +////
         4
         not_exists
         ++/++
         2
         ++/++
         1
         ok
         not_exists
         /////
         5
         ++/++
         2
         2rj9R
         2rq9R
         ok
         +////
         1
         ok
    
    Process returned 0 (0x0)   execution time : 0.053 s
    Press any key to continue.

    è l'output che ottengo dal seguente codice

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    #include <string.h>
    
    #define N 256
    
    typedef struct nodo_
    {
        char *p;
        char *res;
        uint8_t SI[N];
        uint8_t NO[N];
        uint8_t u[N];
        unsigned int u_dim;
        int flag_comp;
        struct nodo_ *next;
    }   nodo;
    
    nodo* aggiungi_nodo_in_ordine(nodo **ptr, char *p, unsigned int k)
    {
        while(*ptr && strcmp((*ptr)->p, p) < 0)
        {
            ptr = &(*ptr)->next;
        }
        nodo *nuovo = (nodo*)malloc(sizeof(nodo));
        nuovo->p = (char*)malloc(sizeof(char) * (k + 1));
        strcpy(nuovo->p, p);
        nuovo->res = (char*)malloc(sizeof(char) * (k + 1));
        *nuovo->res = nuovo->res[k] = '\0';
        nuovo->next = *ptr;
        return(*ptr = nuovo);
    }
    
    nodo* trova_nodo(nodo *ptr, char *p)
    {
        int cmp = 1;
        while(ptr && (cmp = strcmp(p, ptr->p)) > 0)
        {
            ptr = ptr->next;
        }
        return(!cmp ? ptr : NULL);
    }
    
    void definisci_alfabeto(uint8_t *alf)
    {
        for(char c = '0'; c <= '9'; ++alf[c++]);
        for(char c = 'A'; c <= 'Z'; ++alf[c++]);
        for(char c = 'a'; c <= 'z'; ++alf[c++]);
        ++alf['-'];
        ++alf['_'];
    }
    
    int verifica_parola_valida(char *p, uint8_t *alf, unsigned int k)
    {
        unsigned int i;
        for(i = 0; i < k && alf[p[i]]; ++i);
        return(i == k && !p[i]);
    }
    
    int verifica_parola_ammissibile(nodo **ptr, nodo *p_amm, char *p)
    {
        if(!(*ptr = trova_nodo(p_amm, p)))
        {
            printf("     not_exists\n");
        }
        return(*ptr != NULL);
    }
    
    int verifica_parola_compatibile(char *p2, nodo *nd_p)
    {
        uint8_t v[N] = {0};
        unsigned int i;
        for(i = 0; nd_p->p[i] && (nd_p->res[i] == '+' ? p2[i] == nd_p->p[i] : p2[i] != nd_p->p[i] && ++v[p2[i]] && (!nd_p->NO[p2[i]] || nd_p->SI[p2[i]] - v[p2[i]] >= 0)); ++i);
        for(i = !nd_p->p[i] ? 0 : nd_p->u_dim + 1; i < nd_p->u_dim && v[nd_p->u[i]] - nd_p->SI[nd_p->u[i]] >= 0; ++i);
        return(i == nd_p->u_dim);
    }
    
    void aggiungi_nuove_parole_ammissibili(FILE *f, nodo **p_amm, char *input, uint8_t *alf, unsigned int k, int flag_sequenza_iniziale, unsigned int n, unsigned int *n_p_comp)
    {
        while(1)
        {
            fscanf(f, " %s", input);
            if(verifica_parola_valida(input, alf, k))
            {
                nodo *ptr = aggiungi_nodo_in_ordine(p_amm, input, k);
                if(n && *n_p_comp)
                {
                    nodo *temp = *p_amm;
                    while(temp && (!*temp->res || (ptr->flag_comp = verifica_parola_compatibile(ptr->p, temp))))
                    {
                        temp = temp->next;
                    }
                    *n_p_comp += !temp;
                }
            }
            else if(flag_sequenza_iniziale ? *p_amm && !strcmp(input, "+nuova_partita") : !strcmp(input, "+inserisci_fine"))
            {
                break;
            }
        }
    }
    
    void nuova_partita(FILE *f, nodo **nd_r, nodo *p_amm, char *input, uint8_t *alf, unsigned int k, unsigned int *n, unsigned int *n_p_comp)
    {
        do
        {
            fscanf(f, " %s", input);
        }
        while(!verifica_parola_valida(input, alf, k) || !verifica_parola_ammissibile(nd_r, p_amm, input));
        do
        {
            fscanf(f, "%u", n);
        }
        while(!*n);
        while(p_amm)
        {
            *p_amm->res = '\0';
            p_amm->flag_comp = 1;
            p_amm = p_amm->next;
        }
        *n_p_comp = 0;
    }
    
    void stampa_filtrate(nodo *p_amm, unsigned int n_p_comp)
    {
        while(n_p_comp)
        {
            if(p_amm->flag_comp)
            {
                printf("     %s\n", p_amm->p);
                --n_p_comp;
            }
            p_amm = p_amm->next;
        }
    }
    
    void determina_stringa_confronto(char *r, nodo *nd_p)
    {
        memset(nd_p->SI, nd_p->u_dim = 0, sizeof(*nd_p->SI) * N);
        memset(nd_p->NO, 0, sizeof(*nd_p->NO) * N);
        uint8_t v[N] = {0};
        for(unsigned int i = 0; r[i]; ++i)
        {
            if(nd_p->p[i] == r[i])
            {
                nd_p->res[i] = '+';
            }
            else
            {
                nd_p->res[i] = '/';
                ++v[r[i]];
            }
        }
        for(unsigned int i = 0; r[i]; ++i)
        {
            if(nd_p->res[i] == '/')
            {
                if(v[nd_p->p[i]])
                {
                    nd_p->res[i] = '|';
                    --v[nd_p->p[i]];
                    if(!nd_p->SI[nd_p->p[i]]++)
                    {
                        nd_p->u[(nd_p->u_dim)++] = nd_p->p[i];
                    }
                }
                else
                {
                    ++nd_p->NO[nd_p->p[i]];
                }
            }
        }
    }
    
    void determina_parole_compatibili(nodo *p_amm, nodo *nd_r, nodo *nd_p, unsigned int *n_p_comp)
    {
        *n_p_comp = 0;
        while(p_amm)
        {
            if(p_amm == nd_r || p_amm->flag_comp && (p_amm->flag_comp = verifica_parola_compatibile(p_amm->p, nd_p)))
            {
                ++*n_p_comp;
            }
            p_amm = p_amm->next;
        }
    }
    
    int main()
    {
        FILE *f = fopen("test.txt", "r");
        if(f)
        {
            unsigned int k;
            unsigned int n;
            unsigned int n_p_comp;
            nodo *p_amm = NULL;
            nodo *nd_r;
            nodo *nd_p;
            char input[500];
            uint8_t alf[N] = {0};
            definisci_alfabeto(alf);
            do
            {
                fscanf(f, "%u", &k);
            }
            while(!k);
            aggiungi_nuove_parole_ammissibili(f, &p_amm, input, alf, k, 1, 0, &n_p_comp);
            nuova_partita(f, &nd_r, p_amm, input, alf, k, &n, &n_p_comp);
            while(!feof(f))
            {
                fscanf(f, " %s", input);
                if(n && verifica_parola_valida(input, alf, k) && verifica_parola_ammissibile(&nd_p, p_amm, input))
                {
                    if(nd_p == nd_r)
                    {
                        printf("     ok\n");
                        n = 0;
                    }
                    else
                    {
                        determina_stringa_confronto(nd_r->p, nd_p);
                        determina_parole_compatibili(p_amm, nd_r, nd_p, &n_p_comp);
                        printf("     %s\n     %u\n", nd_p->res, n_p_comp);
                        if(!--n)
                        {
                            printf("     ko\n");
                        }
                    }
                }
                else if(n && !strcmp(input, "+stampa_filtrate"))
                {
                    stampa_filtrate(p_amm, n_p_comp);
                }
                else if(!strcmp(input, "+inserisci_inizio"))
                {
                    aggiungi_nuove_parole_ammissibili(f, &p_amm, input, alf, k, 0, n, &n_p_comp);
                }
                else if(!strcmp(input, "+nuova_partita"))
                {
                    nuova_partita(f, &nd_r, p_amm, input, alf, k, &n, &n_p_comp);
                }
                else if(!strcmp(input, "+exit"))
                {
                    break;
                }
            }
            fclose(f);
            return 0;
        }
        return -1;
    }

    ottenuto da quello qui postato sostituendo la lettura da standard input con quella da file (o almeno è quello che ho provato a fare visto i pochi minuti che ho dedicato alla cosa).

    Ovviamente il test effettuato è l'ultimo che hai postato.

  • Re: Progetto di informatica

    I requisiti che ho scritto prima non appartengono a quel test, mea culpa.

    Secondo te (voi), quali potrebbero essere le sequenze più lente del programma? Cosa si potrebbe migliorare?

    Ritengo che il problema si celi nelle strutture dati utilizzate, dal momento che l'algoritmo che hai creato non sembra essere migliorabile.

  • Re: Progetto di informatica

    Non credo si possa fare di meglio per quanto riguarda il confronto e il calcolo delle compatibilità, ma forse mi sbaglio. A qualcuno di voi è venuta in mente una soluzione ancora più efficiente?

  • Re: Progetto di informatica

    01/02/2023 - PhiL99 ha scritto:


    I requisiti che ho scritto prima non appartengono a quel test, mea culpa.

    Ok, ma se non sei in grado di postare almeno un test valido sinceramente non mi va di rincorrere eventuali ottimizzazioni così alla cieca…

  • Re: Progetto di informatica

    Ho trovato il test giusto, ma non posso copia-incollarlo perché è troppo lungo. Come faccio a inviarti il file?

  • Re: Progetto di informatica

    Se non vuoi usare il blocco di codice del forum puoi utilizzare uno dei tanti siti di file hosting gratis in circolazione, questo per esempio è il primo che ho trovato.

  • Re: Progetto di informatica

    Https://easyupload.io/kpg08c

  • Re: Progetto di informatica

    Questo è l'output

    https://easyupload.io/9kwxy6

  • Re: Progetto di informatica

    Forse mi sono perso qualcosa, ma senza gli “a capo” come faccio ad isolare i singoli input?

  • Re: Progetto di informatica

    02/02/2023 - PhiL99 ha scritto:


    Https://easyupload.io/kpg08c

    Non riesci a riportarlo con la seguente formattazione?

    5
    7PGPn
    7PGPU
    2rj9R
    2rF9d
    2rq9R
    2rz9R
    7PkFn
    aPFFn
    2PFdd
    2Zz91
    +nuova_partita
    2rj9R
    11
    2PFdd
    G-kY4
    2rz9R
    2rq9R
    2rj9R
    +nuova_partita
    2rj9R
    18
    DP3wc
    7PGPU
    2rz9R
    +stampa_filtrate
    2rj9R
    +nuova_partita
    2PFdd
    16
    2rq9R
    2PFdd
  • Re: Progetto di informatica

    Ho provato il codice di nippolo su n i5 1,8 GHz

    Il primo collo di bottiglia è aggiungi_nuove_parole_ammissibili() che ci mette sui 15/25 secondi, il resto è sui 3 secondi.

    Sicuramente uno dei problemi è la malloc(), data l'alea del tempo di esecuzione. Prova a non utilizzarla del tutto, che tanto stiamo abbondantemente sotto al MB e puoi tranquillamente allocare in modo statico.

    Un altro problema è l'individuazione del miglior algoritmo di ordinamento per il tuo caso, dati i tempi stretti che ti ha dato per eseguire il tutto. Sicuramente sarà uno dei metodi che vi ha spiegato, altrimenti non vi avrebbe assegnato questo progetto.

    Prova a lavorare su queste due cose e poi si può vedere dove altro tagliare i tempi

  • Re: Progetto di informatica

    Aggiungo anche di fare una prova a risolvere l'esercizio fregandosene dell'ordine lessicografico e aggiungerlo solo alla fine, che magari coi vincoli appresi rimangono solo poche parole ancora valide e non vale la pena ordinare tutto a monte…

  • Re: Progetto di informatica

    @Weierstrass, quando la prima volta ho aperto il file con il blocco note e ho visto un unico blocco di testo continuo, ammetto di non aver nemmeno provato a darlo in pasto al programma. Poi dopo la tua risposta ho fatto un tentativo e ho notato che viene letto correttamente. Chissà come mai il blocco note di windows non mi mostri gli “a capo”?!

    Per il resto devo prima rinfrescarmi la memoria circa la consegna dell'esercizio e l'implementazione che ho adottato.

  • Re: Progetto di informatica

    Perché Windows vuole il Carriage Return + Line Feed, loro usano Linux.

    Direi che basta così: gli hai già fatto la parte più difficile del progetto… :-)

  • Re: Progetto di informatica

    Se io volessi mettere in un array di dimensione 10 solo uno specifico numero, come potrei fare??

Devi accedere o registrarti per scrivere nel forum
73 risposte