Homepage  Il progetto dsy.it è l'unofficial support site dei corsi di laurea del Dipartimento di Scienze dell'Informazione e del Dipartimento di Informatica e Comunicazione della Statale di Milano. E' un servizio degli studenti per gli studenti, curato in modo no-profit da un gruppo di essi. I nostri servizi comprendono aree di discussione per ogni Corso di Laurea, un'area download per lo scambio file, una raccolta di link e un motore di ricerca, il supporto agli studenti lavoratori, il forum hosting per Professori e studenti, i blog, e molto altro...
In questa sezione è indicizzato in textonly il contenuto del nostro forum


.dsy:it. .dsy:it. Archive > Community > Forum De Bell Tolls
 
[INFORMATICA] conteggio stringhe ripetute (C)
Clicca QUI per vedere il messaggio nel forum
Flyzone
Help...mi ritrovo un file di testo di lunghezza massima N, con un tot di stringhe ripetute;
devo contare per ogni parola, quante volte è ripetuta...
Non mi viene in mente un algoritmo decente...o per meglio dire non sò come non far ricontare la stessa parola quando con fseek ritorno al punto di partenza... uffff odio il C per queste cose!
Stò usando fgets fprintf su di un file in input (in sola lettura) e uno in output.

E' per uso personale, non fa parte di nessun progetto della nostra uni (almeno x quel che ne sò io!)

P.S: da evitare esplicitamente puntatori, array bidimensionali, alberi, il file non è ordinato e sopratutto non si possono usare funzioni del C++ :roll: (la ucciderei certa gente)

Hamelin
Non puoi salvare ogni stringa già contata in un array e prima di ogni fseek fare un bel strcmp? Non ho idea di come funzioni fseek perché non l'ho mai usata, quindi potrei dire una marea di str****te....

Flyzone
Originally posted by Hamelin
strcmp?

ma non confrontava due stringhe e basta?
Cioè se strcmp(s1,s2)=0 le stringhe sono uguali altrimenti sono diverse..non mi dice se è _contenuta_ ...
Avrei qualcosa come

ciao sono un gatto nero gatto
come la pece ciao

mi dovrebbe ridare un:
ciao 2
gatto 2
sono 1
pece 1
(etc....)

Hamelin
Ma fseek cosa fa esattamente?

Flyzone
Originally posted by Hamelin
Ma fseek cosa fa esattamente?

se scorri uno stream, la fseek ti permette di posizionarti in una determinata posizione, solitamente viene utilizzata per "riavvolgere" lo stream :)

Hamelin
Ma se tu facessi così, invece?: apri il file in lettura e usando fgets di leggi una dopo
l'altra tutte le parole del file (senza doverlo leggere più volte)... memorizzi la prima
parola in una struct semplicissima che presenta due attributi (un char[] per memorizzare
la stringa di lettera della parola e un int per il numero di occorrenze); dopo di che
per la parola successiva, confronti quello che ti ritorna il fgets con la stringa salvata
nella struct: se è uguale aggiugi 1 al numero di occorrenze, se è diverso costruisci una
nuova struct contenente la nuova parola; alla lettura successiva dovrai usare strcmp con
entrambe le stringhe contenute nelle due struct e così via... naturalmente non è il
massimo della velocità perché è pieno di cicli... ma è semplice e credo che funzioni.

Lord_Tom
Sono d' accordo con Hamelin.
Tuttavia non pensare troppo all' ottimizzazione, se il file che devi processare non è lungo diversi mega bytes.

Un' alternativa è usare un file che memorizza le parole e i relativi contatori.
non guardare la sintassi che è orribile e sbagliata, ma il concetto sottostante
Quindi (scrivo in un pseudo c )
while (!EOF)
{
String mystring = GiveMeNextString();
if (ThisIsNewString(mystring))
{
Myfileadd(mystring);
Myfileadd((char) 0); /* non mi ricordo molto del c come puoi notare... */
}
else {
int posizione = Myfileselect(mystring);
Myfileincrementcount (posizione);
}
/* ora leggiti il file */
}

boolean ThisIsNewString (String mystring)
{
/* scorri il file esaminando ogni stringa
e facendo una strcmp */
if... return true;
return false;
}

Flyzone
Originally posted by Hamelin
Ma se tu facessi così, invece?: apri il file in lettura e usando fgets di leggi una dopo l'altra tutte le parole del file (senza doverlo leggere più volte)

Buona l'idea delle struct, ma la fregatura è che fgets piglia una stringa (si ferma al '\n') e non una parola, ed una riga è lunga all'incirca 5000 caratteri [...].
stavo pensando al fgetc, ma mi ritrovo in cicli e sottocicli cmq...sono a due pagine di roba ufff :sad:
Lo ammetto, in questo caso rimpiango amaramente di non poter usare il visual basic, in 10 minuti era fatto :sad:

Openoffice ha mica una funzione di conteggio delle parole? Hum e avrà mica i sorgenti? :D

Hamelin
...sicuro che fgets si ferma a /n e non a /0? Fossi in te controllerei... bye!

Ryudo

Openoffice ha mica una funzione di conteggio delle parole? Hum e avrà mica i sorgenti? :D [/B]

fai prima a scaricarti le coreutils dal sito di gnu e guardarti i sorgenti di wc ;)

Flyzone
Originally posted by Hamelin
...sicuro che fgets si ferma a /n e non a /0? Fossi in te controllerei... bye!

se lo dice man fgets :D
get = prendi
s = string = stringa = riga = \n ;)

e andiamo ad esaminare stè coreutils :D

Edit: miiiiiiiiiiiiiiiiiiiiiiiiiiii mi ero dimenticato di strtok(NULL," ") :D
ganzo!

DeepBlue
Originally posted by Flyzone
Buona l'idea delle struct, ma la fregatura è che fgets piglia una stringa (si ferma al '\n') e non una parola, ed una riga è lunga all'incirca 5000 caratteri [...].
stavo pensando al fgetc, ma mi ritrovo in cicli e sottocicli cmq...sono a due pagine di roba ufff :sad:
Lo ammetto, in questo caso rimpiango amaramente di non poter usare il visual basic, in 10 minuti era fatto


VB ??? :sbocco:
Cmq con fgets e fseek, con un paio di cicli forse la cosa si risolve. Forse...
Dato che e` una funzione che mi servira` per il prossimo progettino, ora provo a buttare giu` qualcosa.
Ma perche` non vuoi usare i puntatori? Sono specifiche di progetto (naaaa) o ti inorridiscono? :rolleyes:

Gwath
una bella funzione di hash??? così se non c'è la parola la metti nella tabella di hash, se c'è aumenti un contatore di 1... (troppo complicato???)
E poi gli stream non sono oggetti legati al C++ (iostream per l'i/o standard e fstream per l'i/o con files???)

Gw@th

DeepBlue
Originally posted by Gwath
una bella funzione di hash??? così se non c'è la parola la metti nella tabella di hash, se c'è aumenti un contatore di 1... (troppo complicato???)

Deve cmq leggere il file parola per parola, o carattere per carattere e poi costruire l'hash table. Non gli conviene :)


E poi gli stream non sono oggetti legati al C++ (iostream per l'i/o standard e fstream per l'i/o con files???)

mmm generalmente in C si definisce stream una sorgente o una destinazione di dati.
In C++ nin zo

Gwath
Originally posted by DeepBlue
Deve cmq leggere il file parola per parola, o carattere per carattere e poi costruire l'hash table. Non gli conviene :)


Beh ma nei confronti è molto più veloce e poi ha i record già salvati...


mmm generalmente in C si definisce stream una sorgente o una destinazione di dati.
In C++ nin zo


In C++ gli stream sono "classi" di i/o (molto più comode di printf e similari... )

Flyzone
Originally posted by DeepBlue
Cmq con fgets e fseek, con un paio di cicli forse la cosa si risolve. Forse...

un paio? :eek: prego inizia tu!! (non credo proprio che quello che ho scritto sia un paio :D )


Ma perche` non vuoi usare i puntatori? Sono specifiche di progetto (naaaa) o ti inorridiscono? :rolleyes:

La prima che hai detto: specifiche di progetto :roll:
(Della serie: il capo - per niente programmatore - ha in mano un libro proibito :roll: )
Però se ci pensi è meglio così: faccio ovviamente più fatica, ma si impara di più, sotto sotto mi piace :)

DeepBlue
Originally posted by Gwath
Beh ma nei confronti è molto più veloce e poi ha i record già salvati...


Su file molto grossi rende di più una hash table, ne convengo.
Il problema è che non può usare i puntatori, quindi la vedo dura

DeepBlue
Originally posted by Flyzone
un paio? :eek: prego inizia tu!! (non credo proprio che quello che ho scritto sia un paio :D )

Ehm... :P
Dai vedo cosa riesco a scrivere e poi ti faccio sapere :P


La prima che hai detto: specifiche di progetto :roll:
(Della serie: il capo - per niente programmatore - ha in mano un libro proibito :roll: )

Argh! non invidio la tua posizione! Ma cercare di fargli capire i vantaggi anche a runtime che si possono ricavare dall'uso dei puntatori? Fiato sprecato immagino :(

Flyzone
Originally posted by DeepBlue
Fiato sprecato immagino :(

Off-Topic:
psssssssssss se ti dico che vengo pagato a ore... e tanto, dici che conviene sprecare fiato? :D

DeepBlue
Originally posted by Flyzone
Off-Topic:
psssssssssss se ti dico che vengo pagato a ore... e tanto, dici che conviene sprecare fiato? :D


Ti dico: dov'è che lavori? :D

DeepBlue
Ho sfornato una prima versione del programmino.
Ho utilizzato i puntatori pero`, ma magari trai spunto o convinci il tuo capo :P
Volendo il programma si potrebbe ottimizzare ancora un o', vedi tu :)

Se non si legge qui sotto, vai qui

#include <stdio.h>

int main (int argc, char *argv[]){

FILE *fp;
int i=0, z=0, occorrenza=0;
char *stringa;
int dimensione;
char *buffer;
char *posizione;
char loc_buffer[40]={0};
char ch;

if (argc < 2) {
printf("\nParametro mancante. Usare 'cerca parola_da_cercare'\n");
exit(0);
}

stringa=argv[1]; // assegno a stringa la parola da cercare
dimensione=strlen(stringa); // dimensione della parola

if ((fp=fopen("testo.txt","r"))== NULL){
printf("\nIl file non esiste o e` gia` in uso\n");
exit(0);
}
while (fgetc(fp) != EOF) { // conto i caratteri presenti nel testo
i++;
}

printf("\nSalvataggio buffer");
buffer=(char *)malloc(sizeof(char) * (i+1)); // alloco lo spazio per il buffer
fseek(fp, 0, 0); // mi riposiziono all'inizio del file
i=0;
while ((ch = fgetc(fp)) != EOF) { // carico il buffer
buffer[i]=ch;
i++;
}
printf("\nBuffer salvato, inizio controllo");
for( ; z<=i; z++){ // leggo il contenuto del file
if(buffer[z]==stringa[0]){ // confronto il primo carattere della stringa con i char letti
posizione=&buffer[z]; // salvo la posizione del buffer
strncpy(loc_buffer,posizione,strlen(stringa));
// copio N caratteri su un buffer locale x non sporcare l'altro
if (strcmp(loc_buffer, stringa)==0){ // se trovo la stringa incremento il contatore
occorrenza++;
} // if strcmp
} // il confronto
} // ciclo for

fclose(fp);
free((void *) buffer); // libero la memoria
printf("\nSono state trovate %d occorrenze per la parola %s\n", occorrenza, stringa);

return 0;


}

Powered by: vbHome (lite) v4.1 and vBulletin v2.3.1 - Copyright ©2000 - 2002, Jelsoft Enterprises Limited
Mantained by dsy crew (email) | Collabora con noi | Segnalaci un bug | Archive | Regolamento |Licenze | Thanks | Syndacate