Programmazione C - problema di algoritmo

7 risposte [Ultimo messaggio]
Ritratto di anubis
User offline. Last seen 2 ore 8 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno

Allora signori.. questa è la traccia:

data la struttura:

struct pers{<br />
char cognome[MAX_LUNG];<br />
char nome[MAX_LUNG];<br />
char indirizzo[MAX_LUNG];<br />
int  eta;<br />
} anagrafica[MAX_ELE];

e dato il prototipo di funzione:

<br />
struct pers *findPerson(const struct pers *array, int array_size, char *cognome);

scrivere un programma che trovi le persone con il cognome corrispondente a quello ricercato.

in pratica si dovrebbe fare una query e riceve i dati delle persone con lo stesso cognome.

il mio codice:

/*<br />
 * esercitazione-1.c<br />
 * Copyright (C) Andrea Florio 2009 <br />
 *<br />
 * Polinomio is free software: you can redistribute it and/or modify it<br />
 * under the terms of the GNU General Public License as published by the<br />
 * Free Software Foundation, either version 3 of the License, or<br />
 * (at your option) any later version.<br />
 *<br />
 * Polinomio is distributed in the hope that it will be useful, but<br />
 * WITHOUT ANY WARRANTY; without even the implied warranty of<br />
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.<br />
 * See the GNU General Public License for more details.<br />
 *<br />
 * You should have received a copy of the GNU General Public License along<br />
 * with this program.  If not, see .<br />
 */</p>
<p>#include <br />
#include <br />
#define MAX_LUNG 20<br />
#define MAX_ELE 2</p>
<p>struct pers{<br />
char cognome[MAX_LUNG];<br />
char nome[MAX_LUNG];<br />
char indirizzo[MAX_LUNG];<br />
int  eta;<br />
} anagrafica[MAX_ELE];</p>
<p>struct pers *findPerson(const struct pers *, int , char *);<br />
void importPerson (struct pers *);</p>
<p>int main () {</p>
<p>int i;</p>
<p> for (i=0; i
    printf("Digitare i dati per la %d^ persona\n", i+1);<br />
    importPerson(&anagrafica[i]);<br />
    printf("\n");<br />
    }</p>
<p>char surname[MAX_LUNG] = "";<br />
printf("Digita il Cognome da ricercare:\n");<br />
printf("(Attenzione e' case sensitive)\n");<br />
scanf("%s", surname);<br />
printf("\n");</p>
<p>struct pers *found;</p>
<p>found = findPerson(anagrafica, MAX_ELE, surname);</p>
<p>if (found == NULL) {<br />
    printf("Non e' stato trovato nessun riscontro\n");<br />
    return 0;<br />
}<br />
else {</p>
<p>    printf("La persona trovata e':\n");<br />
    printf("Nome: %s\n", found->nome);<br />
    printf("Cognome: %s\n", found->cognome);<br />
    printf("Indirizzo: %s\n", found->indirizzo);<br />
    printf("Eta': %d\n", found->eta);<br />
    printf("\n");<br />
}</p>
<p>#ifdef WIN32<br />
    system("PAUSE");<br />
#endif</p>
<p>return 0;<br />
}</p>
<p>/* Questa funzione ha il difetto di terminare dopo aver trovato il primo elemento<br />
 * la funzione restituisce un puntatore all'elemento individuato, se non<br />
 * esiste alcun riscontro, la funzione ritornerà NULL<br />
 */</p>
<p>struct pers *findPerson(const struct pers *anagrafica, int array_size, char *cognome) {</p>
<p>int i;</p>
<p>  for (i=0; i
<p>    if ( strcmp(anagrafica[i].cognome, cognome) == 0)<br />
        return &anagrafica[i];<br />
    }</p>
<p>    return NULL;<br />
}</p>
<p>/* Inserisci i valori digitati dall'utente nella struttura */<br />
void importPerson (struct pers *mystudente) {</p>
<p>// Il prototipo e' qui, per rispettare il minimo privilegio<br />
    void strip_end (char *, int );</p>
<p>    printf("Digitare il nome:\n");<br />
    fgets(mystudente->nome, MAX_LUNG, stdin);<br />
    strip_end(mystudente->nome,'\n');</p>
<p>    printf("Digitare il cognome:\n");<br />
    fgets(mystudente->cognome, MAX_LUNG, stdin);<br />
    strip_end(mystudente->cognome,'\n');</p>
<p>    printf("Digitare l'indirizzo:\n");<br />
    fgets(mystudente->indirizzo, MAX_LUNG, stdin);<br />
    strip_end(mystudente->indirizzo,'\n');</p>
<p>    printf("Digitare l'eta':\n");<br />
    scanf("\n%d", &mystudente->eta);</p>
<p>/* Devo intercettare "\n" o con un utilizzo ricorsivo<br />
 * di questa funzione, il carattere "\n" andrebbe a<br />
 * terminare l'fgets per aquisire il nome.<br />
 */<br />
    while( getchar()!='\n');<br />
}</p>
<p>/* Questa funzione sostituice con "nul" l'ultima occorrenza del valore c<br />
 * nella stringa s, in questo programma e' utilizzata per eliminare \n dalla<br />
 * stringa importata da fgets, senza rimuoverlo infatti, la stringa non<br />
 * corrispondera' mai con il campo di ricerca<br />
 */<br />
void strip_end (char *s, int c) {</p>
<p>    char *stripend;<br />
    stripend = strrchr(s, c);<br />
    if (stripend != NULL)<br />
    *stripend = 0;<br />
}

il problema è che la funzione è in grado di trovare solo la prima persona con quel cognome in caso di + persone con lo stesso congome.. idee??

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

Ritratto di anubis
User offline. Last seen 2 ore 8 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

bug nella codifica del tag code..

il codice è qui:

http://pastebin.com/m4e869277

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

User offline. Last seen 1 settimana 3 giorni ago. Sconnesso
Iscritto: 12/06/2008
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

found punta alla struttura restituita da findperson

la soluzione piu' semplice sarebbe aggiungere un puntatore "pers *next" nella struttura pers

in findperson il ciclo deve arrivare fino a fine lista e ogni persona trovata deve essere 'appesa' letteralmente al puntatore *next della precedente, cosi' crei una lista di nodi...

alla visualizzazione fai un ciclo che alla fine di ogni nodo salta (tramite *next) al nodo successivo, finche' non trovi un *next che vale NULL

non so se mi sono spiegato bene...

------------x
p.s. ho scritto tempo fa un programma simile in c++, ma il succo e' lo stesso...
se ti puo' essere utile ti passo il sorgente

Ritratto di anubis
User offline. Last seen 2 ore 8 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

non ho studiato e quindi non posso usare,

pile, code, alberi ed allocazione dinamica della memoria...

la tua soluzioni riguarda quindi strutture ricorsive, che in teoria non avrei fatto :(

inoltre sia la struttura, che il prototipo sono dati dalla traccia e non posso essere modificati

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

User offline. Last seen 1 settimana 3 giorni ago. Sconnesso
Iscritto: 12/06/2008
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

ah quindi sei vincolato...

altra soluzione:

crei un'array di puntatori a pers lungo quanto l'intera lista (potrebbero anche avere tutti lo stesso cognome)
e lo inizializzi tutto a null

nel ciclo in findperson scorri tutta la lista
ad ogni persona trovata scrivi il puntatore in una cella dell'array (partendo da arr [0] ovviamente)
per poi passare alla visualizzazione del risultato con un'altro ciclo che si passa l'array finche' non trova una cella null

cosi' sprechi lo spazio di tutte le celle dell'array rimaste inutilizzate, ma non dovresti aver problemi...

Ritratto di anubis
User offline. Last seen 2 ore 8 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

e visto che la funzione DEVE ritornare un puntatore a struct, potrei ritornare il puntatore al primo elemento dell'array..

me gusta.. ci provo subito

di funzionare funziona.. il problema è...

se devo rispettare la traccia (senza modificare il prototipo), faccio una cosa brutta, in quanto il vettore di puntatori è conosciuto dalla funzione in quanto facente parte della funzione chiamante.. se devo programmare come si deve però (e rendere portabile la funzione) , dovrei passare il nome del vettore alla funzione, e questo modificherebbe il prototipo..

uffaaa

:)

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

User offline. Last seen 1 settimana 3 giorni ago. Sconnesso
Iscritto: 12/06/2008
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

per rendere portabile la funzione (senza conoscere l'elenco in precedenza) e fare una cosa pulita, l'unica via e' quella della lista di nodi concatenati credo...

Ritratto di anubis
User offline. Last seen 2 ore 8 min ago. Sconnesso
Iscritto: 07/04/2007
Punti : 0
Gruppi: Nessuno
Re: Programmazione C - problema di algoritmo

per la cronaca, va con queste modifiche:

http://pastebin.com/m495dddba

__________________

OpenSUSE Member,Packman Packager, Education Project Admin, LXDE Project Admin
Powered by http://en.opensuse.org/HP_Pavilion_dv6855el

Condividi contenuti