|
| HOMEPAGE | INDICE FORUM | REGOLAMENTO | ::. | NEI PREFERITI | .:: | RSS Forum | RSS News | NEWS web | NEWS software | |
| PUBBLICITA' | | | ARTICOLI | WIN XP | VISTA | WIN 7 | REGISTRI | SOFTWARE | MANUALI | RECENSIONI | LINUX | HUMOR | HARDWARE | DOWNLOAD | | | CERCA nel FORUM » | |
11-09-2004, 19.52.20 | #1 |
Newbie
Registrato: 04-09-2004
Loc.: (NU)
Messaggi: 5
|
1)RISOLUZIONE PROBLEMA ALGORITMO IN C
Ho un grosso problema: Dovrei risolvere il seguente algoritmo ASSOLUTAMENTE in linguaggio C : "Gli studiosi di testi letterari a volte fanno un esame statistico delle lettere (A,B,..), articoli (Il, lo,...),preposizioni(di, del, al...) e parole presenti in un certo testo. Scrivere un programma che faccia questa analisi stampando per ciascun di questi elementi le percentuali di occorrenza in ordine crescente. Come esempi si prendano testi a carattere matematico, informatico, un aricolo di giornale sportivo, un racconto di uno scrittore". Ho provato ad implementarlo da un pò di tempo ma non riesco a trovare l'errore(che, presumo, sia nella funzione "pmatch"): viene eseguito un ciclo infinito. Il codice è il seguente: #include <stdio.h> #include <malloc.h> #include <stdlib.h> #include <string.h> //Funz ricerca stringa: strstr(); #include <conio.h> #define tot_lettere 36 //Tutte le lettere dell'alfabeto + i numeri del sistema decimale #define dim_max 100 struct lista{ char *parola; int contatore; struct lista *next; }; typedef struct lista list; void spazio (void); void analisi(char *); int pmatch(char *, char *); void insucc(char *); void incrementa_lettera(char ); list *crea_lista(list *, char *); list *confronta_stringa(char *, list *); void stampa(list *); int insuccesso[dim_max]; char lettere[tot_lettere]; //array contenente tutte le lettere dell'alfabeto + num.del sist decimale char max_parola[dim_max]; //Parola massima composta da 25 caratteri char pat[dim_max]; main() { int s, i; char *testo; do { spazio(); printf("\t\tDIGITI:\n\n"); printf("\n1- Analizzare il testo esistente (che verrà visualizzato)\n2- Inserire un nuovo testo\n0- ESCI dal programma"); spazio(); scanf("%d",& s); switch (s){ case 1 : clrscr(); spazio(); printf("Il testo esistente e':"); spazio(); //80 caratteri per riga nella schermata dell'applicativo printf("\nDurante i primi decenni della loro esistenza, le reti di computer sono state\nusate principalmente dai ricercatori universitari per inviare messaggi\nelettronici, e dai dipendenti di industrie per condividere stampanti.\nIn questi ambiti, la segretezza non aveva ragione di esistere.\nInvece adesso, con milioni di comuni cittadini che utilizzano le reti per\noperazioni bancarie, commerciali e fiscali questo problema e' apparso\nell orizzonte come potenzialmente collettivo.\nLa sicurezza in rete e' un argomento vasto e riguarda una moltitudine di\ncrimini.\nNella sua forma piu' semplice, si occupa di assicurare che nessuno possa leggere\no, peggio ancora, modificare i messaggi destinati ad altri. Si occupa di persone\nche cercano di accedere a servizi remoti che non sono autorizzati a usare.\nLa sicurezza si occupa anche di problemi come l intercettazione di messaggi\nautografi e la loro riproduzione, e di persone che cercano di negare di aver\nspedito tali messaggi.\n"); spazio(); testo = "\nDurante i primi decenni della loro esistenza, le reti di computer sono state\nusate principalmente dai ricercatori universitari per inviare messaggi\nelettronici, e dai dipendenti di industrie per condividere stampanti.\nIn questi ambiti, la segretezza non aveva ragione di esistere.\nInvece adesso, con milioni di comuni cittadini che utilizzano le reti per\noperazioni bancarie, commerciali e fiscali questo problema e' apparso\nell orizzonte come potenzialmente collettivo.\nLa sicurezza in rete e' un argomento vasto e riguarda una moltitudine di\ncrimini.\nNella sua forma piu' semplice, si occupa di assicurare che nessuno possa leggere\no, peggio ancora, modificare i messaggi destinati ad altri. Si occupa di persone\nche cercano di accedere a servizi remoti che non sono autorizzati a usare.\nLa sicurezza si occupa anche di problemi come l intercettazione di messaggi\nautografi e la loro riproduzione, e di persone che cercano di negare di aver\nspedito tali messaggi.\n "; printf("\n\n\n\t\t...[INVIO] per continuare...\n"); getchar(); getchar(); clrscr(); analisi(testo); for(i=0; i<tot_lettere; i++) printf("\n%d lettera : %d ", i+1, lettere[i]); break; case 2 : //clrscr(); spazio(); printf("\tINSERISCA UN NUOVO TESTO, tutto su una riga ([INVIO] per terminare):"); gets(testo); //clrscr(); spazio(); printf("\t\tHA INSERITO:"); spazio(); puts(testo); spazio(); printf("\n\n\n\t\t...[INVIO] per continuare...\n"); getchar(); //clrscr(); analisi(testo); break; case 0 : exit(0); default : //clrscr(); printf("\a\t\tSELEZIONE NON PRESENTE!\n\n\t\tDigiti [INVIO] e ripeta la scelta:"); getchar(); break; } } while(s < 0 || s > 2); fflush(stdin); getchar(); } SEGUE NELLA PAGINA PRECEDENTE----------------------------------> |
11-09-2004, 19.56.13 | #2 |
Newbie
Registrato: 04-09-2004
Loc.: (NU)
Messaggi: 5
|
2)RISOLUZIONE PROBLEMA ALGORITMO IN C
<----------------------------------IL CONTINUO:
void spazio(void) { printf("\n--------------------------------------------------------------------------\n"); } //************************************************** ****************** void analisi (char *testo) { int cont = 0, i; list *inizio, *p; inizio = p = NULL; do { //Se la lettera corrente è uguale ad un qualsiasi carattere di punteggiatura si effettua la verifica if(*testo != ',' && *testo != '.' && *testo != ' ' && *testo != '?' && *testo != '!' && *testo != '"' && *testo != '=' && *testo != '\\' && *testo != ':' && *testo != '<' && *testo != '>' && *testo != ';' && *testo != '£' && *testo != '$' && *testo != '%' && *testo != '(' && *testo != ')' && *testo != '*' && *testo != '_' && *testo != '+' && *testo != '-' && *testo != '/' && *testo != '|' && *testo != '#' && *testo != '@' && *testo != '[' && *testo != ']' && *testo != '\0' && *testo != '\'') { incrementa_lettera(*testo); //Incrementa il contatore della lettera max_parola[cont] = *testo; cont++; testo++; } else { if (cont == 0 || cont ==1) //Se è una lettera il suo contatore è già stato incrementato { testo++; cont = 0; } else { inizio = confronta_stringa(max_parola, inizio); } for(i=0; i<tot_lettere; i++) //Inizializziamo a vuoto tutte le componenti dell'array max_parola[i] = '\0'; } } while(*testo != '\0'); } //************************************************** ****************** list *confronta_stringa(char *v, list *inizio) { int flag = -1; while(inizio && flag == -1) //non si è raggiunta la fine del testo e non si è trovata la stringa { flag = pmatch(v, inizio->parola); if(flag != -1) //Se il pattern non è stato trovato pmatch restituisce -1 { inizio->contatore ++; //Incrementa il contatore della stringa esistente return(inizio); } else inizio = inizio->next; } if(flag == -1) inizio = crea_lista(inizio, v); return(inizio); } //************************************************** ****************** int pmatch(char *stringa, char *pat) { int i=0, j=0; int lens = strlen(stringa); int lenp = strlen(pat); insucc(pat); while(i<lens && j<lenp) { if(stringa[i] == pat[j]) {i++; j++;} else if(j==0) i++; else j = insuccesso[j-1]+1; } return( (j==lenp) ? (i-lenp) : -1); } //************************************************** ****************** void insucc(char *pat) { int i, j; int n = strlen(pat); insuccesso[0] = -1; for(j=1; j<n; j++) { i = insuccesso[j-1]; while((pat[j] != pat[i+1]) && (i>=0)) i = insuccesso[i]; if(pat[j] == pat[i+1]) insuccesso[j] = i+1; else insuccesso[j] = -1; } } //************************************************** ****************** list *crea_lista(list *inizio, char *pattern) { list *p, *aux; p = (list *)malloc(sizeof(list)); if(!p) {printf("\nMEMORIA ESAURITA!!"); getchar(); exit(0); } strcpy(p->parola, pattern); p->contatore = 1; p->next = NULL; if(!inizio) return(p); else { aux = inizio; while(aux->next) aux = aux->next; aux->next = p; return(inizio); } } //************************************************** ****************** void stampa (list *inizio) { spazio(); printf("\t\tCOMPOSIZIONE TESTO:"); spazio(); while(inizio) { printf("\n%s compare nel testo %d volte.", inizio->parola, inizio->contatore); inizio = inizio->next; } spazio(); } //************************************************** ****************** void incrementa_lettera(char lettera) { switch (lettera){ case 'a' : case 'A' : lettere[0]++; break; case 'b' : case 'B' : lettere[1]++; break; case 'c' : case 'C' : lettere[2]++; break; case 'd' : case 'D' : lettere[3]++; break; case 'e' : case 'E' : lettere[4]++; break; case 'f' : case 'F' : lettere[5]++; break; case 'g' : case 'G' : lettere[6]++; break; case 'h' : case 'H' : lettere[7]++; break; case 'i' : case 'I' : lettere[8]++; break; case 'j' : case 'J' : lettere[9]++; break; case 'k' : case 'K' : lettere[10]++; break; case 'l' : case 'L' : lettere[11]++; break; case 'm' : case 'M' : lettere[12]++; break; case 'n' : case 'N' : lettere[13]++; break; case 'o' : case 'O' : lettere[14]++; break; case 'p' : case 'P' : lettere[15]++; break; case 'q' : case 'Q' : lettere[16]++; break; case 'r' : case 'R' : lettere[17]++; break; case 's' : case 'S' : lettere[18]++; break; case 't' : case 'T' : lettere[19]++; break; case 'u' : case 'U' : lettere[20]++; break; case 'v' : case 'V' : lettere[21]++; break; case 'w' : case 'W' : lettere[22]++; break; case 'x' : case 'X' : lettere[23]++; break; case 'y' : case 'Y' : lettere[24]++; break; case 'z' : case 'Z' : lettere[25]++; break; case '1' : lettere[26]++; break; case '2' : lettere[27]++; break; case '3' : lettere[28]++; break; case '4' : lettere[29]++; break; case '5' : lettere[30]++; break; case '6' : lettere[31]++; break; case '7' : lettere[32]++; break; case '8' : lettere[33]++; break; case '9' : lettere[34]++; break; case '0' : lettere[35]++; break; default : break; } } |
11-09-2004, 22.48.36 | #3 |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
|
Praticamente devi fare un programma che cerchi una o più occorrenze in un dato testo .. ho capito bene?...
I tipi dati sono stati decisi da te .. o qualcuno ti ha obbligato ad usare le strutture?... Questo algoritmo va fortemente ottimizzato... Bye |
11-09-2004, 22.56.38 | #4 |
Gold Member
Top Poster
Registrato: 07-04-2000
Loc.: Padova-Vicenza
Messaggi: 4.814
|
Ho unito le discussioni: spezzare il tutto in 2 thread genererebbe confusione.
Ah, dimenticavo, caralu: benvenuto!
___________________________________
Con il PC risolvo molti problemi che prima non avevo. - Coltiva Linux che Windows si pianta da solo! |
11-09-2004, 23.03.53 | #5 | |
Gold Member
Registrato: 07-01-2002
Loc.: Milano
Messaggi: 2.863
|
Re: 1)RISOLUZIONE PROBLEMA ALGORITMO IN C
Quota:
Bye |
|
13-09-2004, 13.05.35 | #6 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Io lo riscriverei proprio.
L'esempio non è che sia il massimo della vita però è già un po meglio, almeno dal mio punto di vista. Codice:
#include <stdio.h> #include <string.h> #include <conio.h> #include <ctype.h> #define un 0 #define uno 1 #define una 2 static const char *punt=" !;,.:'?-\n"; short int chr[255],prop[una+1]; char *s=NULL; main(void){ long l=0,i=0,j=0; char car; s="\nDurante i primi decenni della loro esistenza, " "le reti di computer sono state usate principalmente " "dai ricercatori universitari per inviare messaggi elettronici, " "e dai dipendenti di industrie per condividere stampanti.\nIn " "questi ambiti, la segretezza non aveva ragione di esistere. " "Invece adesso, con milioni di comuni cittadini che utilizzano " "le reti per operazioni bancarie, commerciali e fisca li questo " "problema e' apparso nell orizzonte come potenzialmente colletti" "vo. La sicurezza in rete e' un argomento vasto e riguarda una " "moltitudine di crimini.\nNella sua forma piu' semplice, si " "occupa di assicurare che nessuno possa leggere o, peggio ancora, " "modificare i messaggi destinati ad altri.\nSi occupa di persone " "che cercano di accedere a servizi remoti che non sono autorizzati " "a usare.\nLa sicurezza si occupa anche di problemi come l' " "intercettazione di messaggi\nautografi e la loro riproduzione, " "e di persone che cercano di negare di aver spedito tali messaggi.\n"; printf("TESTO DA ANALIZZARE:\n%s",s); memset(chr,0,sizeof(chr)); i=strlen(s)-1; j=strlen(punt); while(*s){ // Conteggio le occorrenze dei singoli caratteri chr[*s]++; switch(*s){ // Controllo un,uno,una case 'u': // Se all'inizio o alla fine del testo if(l==0){ // un if(*(s+1)=='n'&&memchr(punt,*(s+2),strlen(punt))|| (*(s+1)=='n'&&l+1==i))prop[un]++; // uno if(*(s+2)=='o'&&memchr(punt,*(s+3),j)|| (*(s+2)=='o'&&l+3==i))prop[uno]++; // una if(*(s+2)=='a'&&memchr(punt,*(s+3),j)|| (*(s+2)=='a'&&l+3==i))prop[una]++; }else{ // Se all'interno del testo if(memchr(punt,*(s-1),j)){ if(*(s+1)=='n'&&memchr(punt,*(s+2),j)|| (*(s+1)=='n'&&l+1==i))prop[un]++; if(*(s+2)=='o'&&memchr(punt,*(s+3),j)|| (*(s+2)=='o'&&l+3==i))prop[uno]++; if(*(s+2)=='a'&&memchr(punt,tolower(*(s+3)),j)|| (*(s+2)=='a'&&l+3==i))prop[una]++; } }break; }l++;s++; } printf("\nPREMI UN TASTO...\n");getch(); printf("Quale carattere vuoi controllare ?"); scanf("%c",&car); printf("\nIl carattere '%c' e' presente %i volte nel testo.\n",car,chr[car]); printf("il termine 'un' e' presente %i volte nel testo.\n",prop[un]); printf("il termine 'una' e' presente %i volte nel testo.\n",prop[una]); printf("il termine 'uno' e' presente %i volte nel testo.",prop[uno]); getch(); } |
14-09-2004, 00.47.25 | #7 |
Newbie
Registrato: 04-09-2004
Loc.: (NU)
Messaggi: 5
|
Grazie SERGIO, così è molto più leggibile.
Per quanto riguarda WEBMASTER: si, l'algoritmo deve effettuare una ricerca di parole, articoli, lettere e preposizioni in un testo. L'algoritmo che ho scritto io è molto grezzo. Trovo abbastanza buona l'impostazione effettuata da Lory ONe: appena ho un pò di tempo modifico il tuo codice e lo pubblico qua così lo vediamo assieme... A molto presto e grazie a tutti per l'aiuto |
16-09-2004, 16.12.26 | #8 | |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Quota:
|
|
04-10-2004, 19.23.22 | #9 |
Newbie
Registrato: 04-09-2004
Loc.: (NU)
Messaggi: 5
|
chi trova l'errore???
Ho modificato il codice:
siccome devo stampare le parole in ordine di occorrenza crescente (prima quelle che compaiono di meno, poi via via quelle più frequenti), ho introdotto l'algoritmo di ordinamento radix-sort che permette di ordinare la lista in ordine crescente, in modo da stampare la lista delle parole con l'ordine giusto. Nonostante questo ho un problema di compilazione e non riesco a trovare l'errore. L'algoritmo sembra corretto e non riesco a capire cosa abbia sbagliato. Se qualcuno può darmi una mano lo ringrazio davvero tantissimo. Codice:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> //Queste due costanti servono per l'ordinamento radix sort: #define RADICE_SIZE 10 //numero di cifre del sist. decimale #define MAX_CIFRE 3 //numero di cifre da 0 a 999 //Mantiene le frequenze delle lettere int freqLettere['z' - 'a' + 1]; //Array di dimensione 26 (numero di lettere dell'alfabeto) //Mantiene le frequenze dei numeri int freqNumeri[10]; //Dimensione 10 per prendere in considerazione i numeri del sistema decimale //Mantiene il numero totale di caratteri trovati nel testo (lettere e numeri) int totaleCaratteri = 0; //Mantiene il numero totale di parole trovate nel testo int totaleParole = 0; //Definizione dell'elemento di una lista typedef struct list *lista; typedef struct list{ char *parola; int frequenza[MAX_CIFRE]; list *next; }list; //Variabile che mantiene le lista di parole lista parole = NULL; //Inizializza a zero i vettori delle frequenze (lettere e numeri) void inizializza(){ int i; for(i = 0; i < 10; i++) freqNumeri[i] = 0; for(i = 0; i < ('z' - 'a' + 1); i++) freqLettere[i] = 0; } //Aggiorna le frequenze di lettere e numeri void aggiornaFrequenze(char *parola) { int i; char c; int len = strlen(parola); //Memorizza la dimensione di char della parola corrente for(i = 0; i < len; i++) { c = parola[i]; //Memorizza in c la parola corrente //isalpha restituisce un valore diverso da zero se e è una lettera (maiuscola o minuscola) if(isalpha(c)) { //la funzione tolower rende tutte le lettere minuscole c = tolower(c); //incrementiamo la posizione corrispondente di freqLettere freqLettere[c - 'a']++; } //isdigit controlla se il carattere corrente è un numero (in tal caso restituisce un valore diverso da 0) if(isdigit(c)) { //incrementiamo la posizione corrispondente di freqLettere freqNumeri[c - '0']++; } } //Incremento il numero di parole totali totaleParole++; //Incremento il numero di caratteri totali totaleCaratteri = totaleCaratteri + len; } //Restituisce la prossima parola che si trova in testo a partire //dalla posizione posizioneCorrente. Una parola è definita come //una sequenza di lettere e/o numeri senza altri caratteri. //Restituisce NULL se non c'è una prossima parola char *prossimaParola(char *testo) { static int posizioneCorrente = 0; int i; int len = strlen(testo); //len rappresenta il numero dei caratteri presenti nel testo //mi sposto avanti finche non trovo una lettera o un numero while(! isalnum(testo[posizioneCorrente])) { //isalnum restituisce un valore diverso da zero se ciò che analizziamo è un carattere alfanumerico posizioneCorrente++; //se sono alla fine senza aver trovato lettere o numeri ritorno null if(posizioneCorrente >= len) return NULL; } //incremento i finchè trovo numeri e lettere; alla fine del cilco //i punta alla fine della parola corrente i = posizioneCorrente; //in i si registra l'indice dell'array in cui inizia la prima frase del testo while(isalnum(testo[i]) && (i < len)) i++; //i adesso assume il valore dell'indice dell'array che rappresenta la fine della parola int lunghezza = i - posizioneCorrente; //lunghezza è la lunghezza di caratteri della parola considerata char *parola = (char *)malloc((lunghezza + 1)); for(i = 0; i <= lunghezza; i++) parola[i] = testo[posizioneCorrente + i]; //su parola viene memorizzata la parola corrente //Inserisco il carattere di fine stringa alla fine della parola parola[lunghezza] = '\0'; posizioneCorrente = posizioneCorrente + i; //riprende dalla fine della parola return parola; } void stampaNumeri(){ printf("\n\n"); int i; for(i = 0; i < 10; i++) printf("\nfrequenza di %d: %d", i, freqNumeri[i]); } void stampaLettere(){ printf("\n\n"); int i; for(i = 0; i < ('z' - 'a' + 1); i++) printf("\nfrequenza di %c: %d", 'a' + i, freqLettere[i]); } void stampaParole(){ printf("\n\n"); lista temp = parole; while(temp){ printf("\nfrequenza di %s: %d", temp->parola, temp->frequenza[0]); temp = temp -> next; } } //Inserisce la parola nella lista parole, se non è gia presente, //altrimenti incrementa la sua frequenza void inserisciParola(char *parola){ lista temp = parole; //Scorriamo la lista per vedere se la parola è ia stata inserita while(temp){ //Se la parola già c'è ci limitiamo a incrementare //la frequenza if(strcmp(temp -> parola, parola) == 0) //se strcmp restituisce 0 le stringhe sono uguali { temp->frequenza[2] = temp->frequenza[2]%RADICE_SIZE; temp->frequenza[1]=(temp->frequenza[1] % (RADICE_SIZE*RADICE_SIZE))/RADICE_SIZE; temp->frequenza[0]=(temp->frequenza[0] % (RADICE_SIZE*RADICE_SIZE*RADICE_SIZE))/(RADICE_SIZE*RADICE_SIZE); return; } temp = temp -> next; } //Se la parola non è stata trovata, creiamo un nuovo elemento //che sarà inserito in testa alla lista. temp = (lista )malloc(sizeof(lista)); temp -> parola = parola; temp -> frequenza[0] = 1; temp -> next = parole; //Facciamo puntare la lista 'parole' all'elemento di testa //appena isnerito parole = temp; } /*questa funzione crea dei "recipienti" per rappresentare il valore delle chiavi (sono 10 recipienti, da 0 a 9). Visto che un numero intero è costituito da più cifre ordinate dalla meno significativa, in ultima posizione, alla più significativa, in prima posizione (000, 001, 002,..., 010,...,100,..., 999) e ogni cifra K si trova nell'intervallo 0 <= k <= 9 ,in questo tipo di ordinamento la chiave di ordinamento viene scomposta in cifre utilizzando una radice RADICE_SIZE*/ lista radice_sort(lista ptr) { lista davanti[RADICE_SIZE], dietro[RADICE_SIZE]; int i, j, cifra; for(i=MAX_CIFRE-1;i>=0;i--) { for(j=0;j<RADICE_SIZE;j++) davanti[j] = dietro[j] = NULL; //i recipienti sono //implementati come code di dati: davanti[i] punta al primo //record nel recipiente i, mentre dietro[i] punta all'ultimo //record nel recipiente i. while(ptr) { cifra = ptr->frequenza[i]; if(!davanti[cifra]) davanti[cifra] = ptr; else dietro[cifra]->next = ptr; dietro[cifra] = ptr; ptr = ptr->next; } ptr = NULL; for(j=RADICE_SIZE-1;j>=0;j--) { if(davanti[j]) { dietro[j]->next = ptr; ptr = davanti[j]; } } } return ptr; } int main(){ char * p; char *testo = "ciao\tt\n1r&7 (re)re t zz"; while((p = prossimaParola(testo))){ aggiornaFrequenze(p); inserisciParola(p); } stampaNumeri(); stampaLettere(); parole = radice_sort(parole); stampaParole(); printf("\n\nTotale parole: %d", totaleParole); printf("\n\nTotale caratteri: %d", totaleCaratteri); fflush(stdin); getchar(); } |
05-10-2004, 09.48.08 | #10 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Il problema sembra risiedere in ProssimaParola, subito dopo questa istruzione:
char *parola = (char *)malloc((lunghezza + 1)); |
05-10-2004, 20.21.09 | #11 |
Newbie
Registrato: 04-09-2004
Loc.: (NU)
Messaggi: 5
|
Il problema dev'essere all'interno della funzione "inserisciParola", ma non riesco ad individuarlo, gli assegnamenti mi sembrano corretti, eppure....
Mi serve che lo analizzi un esterno. Spero che qualcuno riesca a trovare un po di tempo e pazienza per farlo. Grazie a chi lo facesse |
05-10-2004, 22.13.08 | #12 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
Si, può anche essere e forse esplode pure quando esegui il sort ma andiamo con ordine:
Compilato così com'è non da problemi ma quando lo lancio esplode. E' tipico quando si lavora con i puntatori e quindi è necessario fare molta attenzione. La priam funzione che viene richiamata è "ProssimaParola", quindi analizziamo prima questa. Funziona tutto fino a: char *parola = (char *)malloc((lunghezza + 1)); poi quel for...fa esplodere tutto. Io mi chiedo: Se conosci la lunghezza a priori, perchè allochi memoria dinamica ? Non sarebbe più semplice definire char parola[lunghezza] ? |
05-10-2004, 22.17.15 | #13 |
Gold Member
WT Expert
Registrato: 09-01-2002
Loc.: None of your business
Messaggi: 5.505
|
...intanto ti propongo un'altra visione della cosa, però prima cerchiamo di risolvere il problema col tuo listato
|
06-10-2004, 12.35.40 | #14 |
Linux Supporter
Registrato: 02-12-2000
Loc.: Monza
Messaggi: 1.987
|
Codice:
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <ctype.h> //Queste due costanti servono per l'ordinamento radix sort: #define RADICE_SIZE 10 //numero di cifre del sist. decimale #define MAX_CIFRE 3 //numero di cifre da 0 a 999 //Mantiene le frequenze delle lettere int freqLettere['z' - 'a' + 1]; //Array di dimensione 26 (numero di lettere dell'alfabeto) //Mantiene le frequenze dei numeri int freqNumeri[10]; //Dimensione 10 per prendere in considerazione i numeri del sistema decimale //Mantiene il numero totale di caratteri trovati nel testo (lettere e numeri) int totaleCaratteri = 0; //Mantiene il numero totale di parole trovate nel testo int totaleParole = 0; //Definizione dell'elemento di una lista //typedef struct list *lista; typedef struct list{ char *parola; int frequenza[MAX_CIFRE]; struct list *next; } list; //Variabile che mantiene le lista di parole struct list *parole = NULL; //Inizializza a zero i vettori delle frequenze (lettere e numeri) void inizializza(){ int i; for(i = 0; i < 10; i++) freqNumeri[i] = 0; for(i = 0; i < ('z' - 'a' + 1); i++) freqLettere[i] = 0; } //Aggiorna le frequenze di lettere e numeri void aggiornaFrequenze(char *parola) { int i; char c; int len = strlen(parola); //Memorizza la dimensione di char della parola corrente for(i = 0; i < len; i++) { c = parola[i]; //Memorizza in c la parola corrente //isalpha restituisce un valore diverso da zero se e è una lettera (maiuscola o minuscola) if(isalpha(c)) { //la funzione tolower rende tutte le lettere minuscole c = tolower(c); //incrementiamo la posizione corrispondente di freqLettere freqLettere[c - 'a']++; } //isdigit controlla se il carattere corrente è un numero (in tal caso restituisce un valore diverso da 0) if(isdigit(c)) { //incrementiamo la posizione corrispondente di freqLettere freqNumeri[c - '0']++; } } //Incremento il numero di parole totali totaleParole++; //Incremento il numero di caratteri totali totaleCaratteri = totaleCaratteri + len; } //Restituisce la prossima parola che si trova in testo a partire //dalla posizione posizioneCorrente. Una parola è definita come //una sequenza di lettere e/o numeri senza altri caratteri. //Restituisce NULL se non c'è una prossima parola char *prossimaParola(char *testo) { static int posizioneCorrente = 0; int i; int len = strlen(testo); //len rappresenta il numero dei caratteri presenti nel testo //mi sposto avanti finche non trovo una lettera o un numero while(! isalnum(testo[posizioneCorrente])) { //isalnum restituisce un valore diverso da zero se ciò che analizziamo è un carattere alfanumerico posizioneCorrente++; //se sono alla fine senza aver trovato lettere o numeri ritorno null if(posizioneCorrente >= len) return NULL; } //incremento i finchè trovo numeri e lettere; alla fine del cilco //i punta alla fine della parola corrente i = posizioneCorrente; //in i si registra l'indice dell'array in cui inizia la prima frase del testo while(isalnum(testo[i]) && (i < len)) i++; //i adesso assume il valore dell'indice dell'array che rappresenta la fine della parola int lunghezza = i - posizioneCorrente; //lunghezza è la lunghezza di caratteri della parola considerata char *parola = (char *)malloc((lunghezza + 1)); for(i = 0; i <= lunghezza; i++) parola[i] = testo[posizioneCorrente + i]; //su parola viene memorizzata la parola corrente //Inserisco il carattere di fine stringa alla fine della parola parola[lunghezza] = '\0'; posizioneCorrente = posizioneCorrente + i; //riprende dalla fine della parola return parola; } void stampaNumeri(){ printf("\n\n"); int i; for(i = 0; i < 10; i++) printf("\nfrequenza di %d: %d", i, freqNumeri[i]); } void stampaLettere(){ printf("\n\n"); int i; for(i = 0; i < ('z' - 'a' + 1); i++) printf("\nfrequenza di %c: %d", 'a' + i, freqLettere[i]); } void stampaParole(){ printf("\n\n"); struct list *temp = parole; while(temp){ printf("\nfrequenza di %s: %d", temp->parola, temp->frequenza[0]); temp = temp -> next; } } //Inserisce la parola nella lista parole, se non è gia presente, //altrimenti incrementa la sua frequenza void inserisciParola(char *parola){ struct list *temp = parole; //Scorriamo la lista per vedere se la parola è ia stata inserita while(temp){ //Se la parola già c'è ci limitiamo a incrementare //la frequenza if(strcmp(temp -> parola, parola) == 0) //se strcmp restituisce 0 le stringhe sono uguali { temp->frequenza[2] = temp->frequenza[2]%RADICE_SIZE; temp->frequenza[1]=(temp->frequenza[1] % (RADICE_SIZE*RADICE_SIZE))/RADICE_SIZE; temp->frequenza[0]=(temp->frequenza[0] % (RADICE_SIZE*RADICE_SIZE*RADICE_SIZE))/(RADICE_SIZE*RADICE_SIZE); return; } temp = temp -> next; } //Se la parola non è stata trovata, creiamo un nuovo elemento //che sarà inserito in testa alla lista. temp = (struct list *)malloc(sizeof(struct list)); temp -> parola = parola; temp -> frequenza[0] = 1; temp -> next = parole; //Facciamo puntare la lista 'parole' all'elemento di testa //appena isnerito parole = temp; } /*questa funzione crea dei "recipienti" per rappresentare il valore delle chiavi (sono 10 recipienti, da 0 a 9). Visto che un numero intero è costituito da più cifre ordinate dalla meno significativa, in ultima posizione, alla più significativa, in prima posizione (000, 001, 002,..., 010,...,100,..., 999) e ogni cifra K si trova nell'intervallo 0 <= k <= 9 ,in questo tipo di ordinamento la chiave di ordinamento viene scomposta in cifre utilizzando una radice RADICE_SIZE*/ struct list * radice_sort(struct list *ptr) { struct list *davanti[RADICE_SIZE], *dietro[RADICE_SIZE]; int i, j, cifra; for(i=MAX_CIFRE-1;i>=0;i--) { for(j=0;j<RADICE_SIZE;j++) davanti[j] = dietro[j] = NULL; //i recipienti sono //implementati come code di dati: davanti[i] punta al primo //record nel recipiente i, mentre dietro[i] punta all'ultimo //record nel recipiente i. while(ptr) { cifra = ptr->frequenza[i]; if(!davanti[cifra]) davanti[cifra] = ptr; else dietro[cifra]->next = ptr; dietro[cifra] = ptr; ptr = ptr->next; } ptr = NULL; for(j=RADICE_SIZE-1;j>=0;j--) { if(davanti[j]) { dietro[j]->next = ptr; ptr = davanti[j]; } } } return ptr; } int main(){ char * p; char *testo = "ciao\tt\n1r&7 (re)re t zz"; while((p = prossimaParola(testo))){ aggiornaFrequenze(p); inserisciParola(p); } stampaNumeri(); stampaLettere(); parole = radice_sort(parole); stampaParole(); printf("\n\nTotale parole: %d", totaleParole); printf("\n\nTotale caratteri: %d", totaleCaratteri); fflush(stdin); getchar(); } Ora e' a posto nn crasha piu'.. Hai usato male i puntatori e le liste, in particolare: typedef struct list *lista; typedef struct list{ char *parola; int frequenza[MAX_CIFRE]; lista *next; } list; nn e' corretto.. Ciao |
Utenti attualmente attivi che stanno leggendo questa discussione: 1 (0 utenti e 1 ospiti) | |
Strumenti discussione | |
|
|
Discussioni simili | ||||
Discussione | Autore discussione | Forum | Risposte | Ultimo messaggio |
problema internet explorer lentissimo | filo_2k | Internet e Reti locali | 18 | 07-01-2008 09.24.20 |
Problema di comunicazione col masterizzatore | Shumila | Masterizzazione Giochi Games | 4 | 13-09-2007 07.40.31 |
Problema Pinnacle PCTV Pro e periferiche IDE | exion | Hardware e Overclock | 56 | 30-01-2005 11.44.47 |
Problema con la masterizzazione... la colpa è della Audigy!!! Qualche idea??? | LaBrie | Windows 7/Vista/XP/ 2003 | 13 | 31-01-2004 15.28.25 |
Problema di lentezza ma solo certi momenti | Marko | Windows 7/Vista/XP/ 2003 | 3 | 12-09-2003 16.01.19 |