Newsgroup: it.comp.lang.c
Titolo: Creare una classifica delle parole più frequenti in un file di testo

Dato un file di testo, devo costruire una classifica delle parole
presenti in esso e creare un secondo file che mostri in ogni riga le
occorrenze di ciascuna parola. Esempio:
Contenuto del file da analizzare:
aaa bbbccc aa nnnnn bbbbbb aaa aaa bbbccc
Contenuto del file da creare:
aaa 3
bbbccc 2
aa 1
nnnnn 1
bbbbbb 1
Qualcuno ha dei suggerimenti su come sviluppare questo programma?

Simone (Demo) Gentili ha scritto:

cerca binary search tree

 Qualcuno ha dei suggerimenti su come sviluppare questo programma?
tokenizzi le parole (presumo basti usare lo spazio come separatore), le
inserisci in un dizionario (una tabella hash non ci si mette molto a farla)
contando quante volte ogni parole è presente. (eventualmente) ordini le
parole per frequenza e infile le butti sul file di output.
-- 
By ZeD

 Qualcuno ha dei suggerimenti su come sviluppare questo programma?
IIRC questo e' l'esempio standard su "Practice of Programming" di
Kernighan e Pike.
-- 
-riko

 parole per frequenza e infile le butti sul file di output.
Ok, adesso la parte difficile: come fare queste cose?
Nel forum di Ubuntu ho ricevuto in continuazione risposte come "devi
fare così così e poi così", ma mai ho avuto come aiuto la sintassi.
Dove trovo del codice, o le funzioni necessarie per fare token e hash
table? Non voglio il codice pronto, ma solo capire quali sono le
funzioni da usare. Spero che almeno qui qualcuno voglia darmi una
mano.
Ora vado a cercare ... Ciao beli

 mano.
Ma quanto sai di C?
-- 
By ZeD


-- 
-riko

Simone (Demo) Gentili ha scritto:

A costo di ricevere una cassettata di pomodori e uova informatiche nella 
schiena (o forse arance, ricche di vitamina C), specialmente se questa 
cosa non la devi fare per inserirla in un programma scritto in C, ti 
consiglio di NON usare il C, bens� qualche linguaggio interpretato che 
fornisce gi� le strutture dati adatte. Mi viene in mente Ruby.
Me la do a gambe....
Giovanni

 fornisce già le strutture dati adatte. Mi viene in mente Ruby.
va bene in python? :)
#!/usr/bin/env python
# USO: NOMEPROGRAMMA FILEIN FILEOUT
from sys import argv
from collections import defaultdict
d = defaultdict(lambda: 0)
with open(argv[1]) as filein:
    for row in filein:
        for word in row.split():
            d[word] += 1
with open(argv[2], 'w') as fileout:
    for pair in sorted(d.items(), key=lambda (k,v): (v,k), reverse=True):
        fileout.write("%s: %s\n" % pair)
in realtà a meno di casi molto particolari, questa richiesta puzza di
compitino da fare (esame del primo anno d'università?) e quindi risolverla
in un linguaggio in alto livello non penso sia di interessere per l'OP.
Magari puo' dargli una visione d'insieme, ma, in pratica, mi sono limitato a
riscrivergli in codice quello che gli ho suggerito a parole.
-- 
By ZeD

 riscrivergli in codice quello che gli ho suggerito a parole.
Beh, lui voleva la sintassi e io la sintassi l'ho data...
Eppure non mi ha mica detto grazie.
-- 
-riko

Rispondo un pochino a tutti:
Non è che puzza: è un esame. Per quello non voglio codice, ma solo una
mano a raggiungere l'obiettivo. Non mi piace il copia incolla : ti
spegne la mente.
No purtroppo lo devo fare in C.
Di C non ne so abbastanza purtroppo =( ma si studia ...
Grazie per il libro. Spero mi sia utile.
Conclusioni: meglio partire da quello che ho fatto sino a questo
momento. Il resto del programma l'ho fatto l'altra notte in due ore.
Questa parte l'ho fatta un migliaio di volte senza cavarci fuori
qualche cosa di utile.
Vi dico che cosa deve fare il programma: devo aprire un file di testo,
e poi comprimerlo usando l'algoritmo RLE
Se il contenuto del file è:
wwwwwwwooooooooooooo
Io lo devo trasformare in:
7w13o
Questo "7w13o" ho deciso di scriverlo in un modo particolare che mi
permette di scrivere 3 byte anzichè 5. Non entro nel dettaglio. Ho
trovato del codice per delle hash table e funziona!!! Incredibile!!!
Inizio a fare i test e BAAAAAAAAM Le hash table che stavo usando hanno
dei problemi con chiavi troppo lunghe. AMEN! Riproviamo a fare tutto
da capo (la parte della compressione è OK):
[...] la parte delle statistiche:
Sono convinto che per molti di voi questo è l'ABC. Il mio problema è
che non so entrare del tutto nell'ottica del C. Sono programmatore php
e li non ho avuto mai grossi problemi. Trovo che la documentazione sia
ottima per php. In C. Io .. credo di non essere in grado di cercare le
informazioni che mi servono perchè vi assicuro che google me lo sono
scartabellato e non ho trovato nulla di utile.
Vi racconto anche che in uno dei miei tentativi ho fatto delle banali
fsccanf del file. Eheheh nella parte della compressione usavo fgetc
(mentre leggevo nel file da comprimere) ed fputc (quando scrivevo nel
file compresso).
Un'alternativa a tutto questo, sarebbe postare qui il codice delle
hash table, e vedere insieme se potete farmi capire come mai le chiavi
non fungono.
PRIMO PASSO:
(Come primo passo avevo pensato alla struttura dati: non conosco il
numero di parole e non conosco la loro singola lunghezza)
int main(void)
{
    char *parole[0];
    char *parola;
    int num_parole_inserite = 0;
    parola=malloc(sizeof(char));
    strcpy
(parola,"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
    strcpy(parole[num_parole_inserite],parola);
    fprintf(stdout,"strlen(parole[%d]) = %d (='%s')
\n",num_parole_inserite,strlen(parole[0]),parole[0]);
    fflush(stdout);
    num_parole_inserite++;
    *(parole+num_parole_inserite)=malloc(sizeof(char));
    strcpy(parola,"bbbbbbbbbbbbb");
    strcpy(parole[num_parole_inserite],parola);
    fprintf(stdout,"strlen(parole[%d]) = %d (='%s')
\n",num_parole_inserite,strlen(parole[num_parole_inserite]),parole
[num_parole_inserite]);
    fflush(stdout);
    num_parole_inserite++;
    *(parole+num_parole_inserite)=malloc(sizeof(char));
    strcpy(parola,"cccccccccccccccccccccccccc");
    strcpy(parole[num_parole_inserite],parola);
    fprintf(stdout,"strlen(parole[%d]) = %d (='%s')
\n",num_parole_inserite,strlen(parole[num_parole_inserite]),parole
[num_parole_inserite]);
    fflush(stdout);
    num_parole_inserite++;
    return 0;
}
Avete idea del perchè questa struttura a lungo andare genera un
Segmentation fault?

 Segmentation fault?
in 2 parole?
buffer overflow.
per la cronaca, questo è l'elenco degli errori che mi da il gcc:
$ make err
cc -Werror -Wall -Wextra -Wold-style-definition -Wmissing-declarations -Wredundant-decls -Wmissing-noreturn -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Winline -Wformat-nonliteral -Wformat-security -Wswitch-enum -Wswitch-default -Winit-self -Wmissing-include-dirs -Wundef -Waggregate-return -Wmissing-format-attribute -Wnested-externs -std=c99 -pedantic   
err.c   -o err
cc1: warnings being treated as errors
err.c: In function ‘main’:
err.c:4: error: ISO C forbids zero-size array ‘parole’
err.c:7: error: implicit declaration of function ‘malloc’
err.c:7: error: incompatible implicit declaration of built-in
function ‘malloc’
err.c:9: error: implicit declaration of function ‘strcpy’
err.c:9: error: incompatible implicit declaration of built-in
function ‘strcpy’
err.c:11: error: implicit declaration of function ‘fprintf’
err.c:11: error: incompatible implicit declaration of built-in
function ‘fprintf’
err.c:11: error: ‘stdout’ undeclared (first use in this function)
err.c:11: error: (Each undeclared identifier is reported only once
err.c:11: error: for each function it appears in.)
err.c:11: error: implicit declaration of function ‘strlen’
err.c:11: error: incompatible implicit declaration of built-in
function ‘strlen’
err.c:12: error: implicit declaration of function ‘fflush’
err.c:12: error: nested extern declaration of ‘fflush’
make: *** [err] Error 1
$
-- 
By ZeD