esercizio su stringhe e strutture

tsle

Nuovo Utente
13
1
Buongiorno a tutti, gli esercizi di programmazione diventano via via più complessi passando dal semplice uso di stringhe a questo. Non avendo nessuno con cui confrontarmi chiedo a voi.

Scrivere un programma legga linea per linea dallo standard input,
costruendo una tabella di parole (sequenza alfabetiche separate da
punteggiatura o spazi), contando quante volte compare ogni parola.
Alla fine stampa tutte le parole distinte trovate con il numero di
occorrenze per ognuna.
Considerare una dimensione massima per le linee in input (es. 250),
un numero massimo di parole distinte gestibili (es. 1000), ed una
lunghezza massima delle parole (es. 26).

Non riesco a capire come strutturare il programma e come implementare il riconoscimento delle parole.
Spero di non rubare troppo tempo a nessuno.
In qualsiasi caso grazie della risposta.
 

bigendian

Utente Attivo
750
432
OS
Linux
E' un bell'esercizio :)

Non ci hai detto il linguaggio. Se in C

Si puo fare in vari modi, per mantenerlo semplice lo farei cosi:
creerei una tabella statica di 1000 strutture, per non allocare nulla.

Codice:
struct entry {
    char parola[26 + 1];
    int cnt;
};

Poi un parser che scorre la linea, e aggiunge le parole alla tabella se non gia presenti.

Alla fine con un ciclo for stampi le parole e il contatore per parola.
 

Andretti60

Utente Èlite
6,440
5,091
Per favore leggi il regolamento di sezione, devi pubblicare quello che fatto finora (anche se sbagliato) in modo che possiamo anche capire quale sia il tuo livello. E devi dire quale sia il linguaggio di programmazione da usare.
 

tsle

Nuovo Utente
13
1
Ciao a tutti. Scusate per la mancanza di informazioni che vi ho fornito.
Il linguaggio di programmazione è il C e l' esercizio antecede gli argomenti di allocazione ecc...
Vettori, puntatori, stringhe, strutture e unioni sono gli argomenti che antecedono questo esercizio(tralasciando quelli proprio iniziali)
Vi ringrazio molto per l' aiuto.
 

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Ciao, ti aiuteremo volentieri, ma prima di tutto pubblica ciò che hai fatto, anche incompleto o non funzionante. Altrimenti vorrebbe dire darti del codice pronto da copiare/incollare.
 
  • Mi piace
Reazioni: Ibernato e Mursey

Ibernato

Utente Èlite
4,330
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Ciao a tutti. Scusate per la mancanza di informazioni che vi ho fornito.
Il linguaggio di programmazione è il C e l' esercizio antecede gli argomenti di allocazione ecc...
Vettori, puntatori, stringhe, strutture e unioni sono gli argomenti che antecedono questo esercizio(tralasciando quelli proprio iniziali)
Vi ringrazio molto per l' aiuto.
Quindi fino ad ora cosa ha spiegato il docente?
Almeno gli array e i char immagino li abbia spiegati
 

Ibernato

Utente Èlite
4,330
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Sisisi ha spiegato fino alle strutture e unioni.
Quindi potresti partire dal suggerimento di @bigendian e poi postare qui quello che hai fatto.
Se hai qualcosa di già fatto, postalo :)
Il riconoscimento delle parole lo puoi fare con la funzione compare (strcmp) presente nella libreria string.h
Hai un altro suggerimento!
Sarebbe un male incollarti la soluzione.
 

tsle

Nuovo Utente
13
1
Salve a tutti. Sono riuscito a scrivere una bozza dell' esercizio ,ma ci sono dei passaggi che non so come fare; ad esempio fermare l' inserimento e iniziare la verifica delle parole uguali. Vi ringrazio del vostro aiuto.


C:
#include <stdio.h>
#include <string.h>

int main(){

    int i;
    int s;

    struct insieme {
        char parola[100];
        int conta;
    };

    struct insieme frasi[100];

    printf("Inserisci le parole\n");

    for(i=0;i<100;i++){
        for(s=0;s<100;s++){
            scanf("%s", frasi[i].parola);

            while (frasi[i].parola!='\n'){
                if (frasi[i].parola==frasi[i-s].parola){
                    frasi[i].conta+1;
                }
            }  
       }
    }

    for(i=0;i<100;i++){
        printf("la parola: %s è ripetuta : %d", frasi[i].parola, frasi[i].conta);
    }   

    return 0;     

}
 
Ultima modifica da un moderatore:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Ciao, ti ho formattato il codice ed ho inserito il tag CODE. La prossima volta che pubblichi del codice utilizzalo per favore, trovi tutte le info nel regolamento di sezione.

Questa parte di codice in realtà è sbagliata:

C:
            while (frasi[i].parola!='\n'){
                if (frasi[i].parola==frasi[i-s].parola){
                    frasi[i].conta+1;
                }
            }

Il confronto con '\n' è errato; il terminatore della stringa è \0. Inoltre ti converrebbe calcolare la lunghezza della parola inserita con strlen.
Non è corretto però come lo stai impostando: secondo me ti conviene seguire il consiglio di bigendian.

Il confronto tra due stringhe lo si fa con int strncmp ( const char * str1, const char * str2, size_t num ); , non con "==".
Anche il modo in cui hai impostato il loop è errato: nel primo ciclo hai solo l'elemento in posizione 0, quindi andresti a fare il confronto sulla stessa parola.
 
  • Mi piace
Reazioni: Mursey

tsle

Nuovo Utente
13
1
Ora ci provo. Grazie mille per la gentilezza, non padroneggio ancora tutti questi concetti. Scusate per le mancanze sulle regole del forum. Farò molta più attenzione.
Non capisco perchè converrebbe calcolare la lunghezza della stringa. Per compararle?
 
  • Adoro
Reazioni: DispatchCode

Ibernato

Utente Èlite
4,330
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Ma non sarebbe comodo inserire tutte le parole in un'unica frase della scanf e poi fare il check? (piuttosto che inserire 100 parole a mano ogni volta). Cioè hai il vincolo che vuoi 100 parole solamente, bene, digito una frase lunga e scarto quando ho raggiunto 100 parole. Mi sembra che la traccia intendesse questo.

Tra l'altro, mi immagino che quella struct deve avere parole distinte e non possibili duplicazione. Queste utlime vanno semplicemente contate come occorrenze.
Quindi, quando inserisci una parola già presente, non deve essere aggiunta alla struct.
Spero di aver interpretato bene il problema.
Se così, piuttosto che fare la scanf sulla struct, falla su una variabile stringa, se quella stringa è già presente nella struct, contala come occorrenza, altrimenti aggiungi la stringa alla struct
 
Ultima modifica:

DispatchCode

Moderatore
Staff Forum
Utente Èlite
2,223
1,854
CPU
Intel I9-10900KF 3.75GHz 10x 125W
Dissipatore
Gigabyte Aorus Waterforce X360 ARGB
Scheda Madre
Asus 1200 TUF Z590-Plus Gaming ATX DDR4
HDD
1TB NVMe PCI 3.0 x4, 1TB 7200rpm 64MB SATA3
RAM
DDR4 32GB 3600MHz CL18 ARGB
GPU
Nvidia RTX 3080 10GB DDR6
Audio
Integrata 7.1 HD audio
Monitor
LG 34GN850
PSU
Gigabyte P850PM
Case
Phanteks Enthoo Evolv X ARGB
Periferiche
MSI Vigor GK30, mouse Logitech
Net
FTTH Aruba, 1Gb (effettivi: ~950Mb / ~480Mb)
OS
Windows 10 64bit / OpenSUSE Tumbleweed
Non capisco perchè converrebbe calcolare la lunghezza della stringa. Per compararle?

Ho visto che verificavi se frase[i].parola == '\n', questo è proprio errato; se vuoi verificare un particolare carattere della parola devi specificare il suo indice. Per farlo ti serve sapere quanto è lunga la stringa e prendere l'ultimo carattere.

//qui piuttosto che usare il while, metti strctmp

Meglio utilizzare strncmp, come suggerivo sopra; effettua il compare ma riceve anche in input la lunghezza della stringa (per evitare bug).
Ma non sarebbe comodo inserire tutte le parole in un'unica frase della scanf e poi fare il check?
Potrebbe anche fare quello, ma scanf non legge una stringa; bisognerebbe modificare il "format" della scanf, ma a questo punto meglio usare fgets per evitare buffer overflows.
Inoltre se fa così, deve poi spezzare comunque la stringa in parole, visto che il confronto va fatto su parole.

Ma non ho messo molto la testa sul problema in questione, non ho avuto modo, non vorrei dire inesattezze relative all'implementazione.
 

Ibernato

Utente Èlite
4,330
2,047
OS
Windows 10 Pro / Ubuntu 22.04
Meglio utilizzare strncmp, come suggerivo sopra; effettua il compare ma riceve anche in input la lunghezza della stringa (per evitare bug).
Ho editato il messaggio perchè non potendolo testare, ad occhio, ci sono dei problemi sicuramnete (tra cui l'inserimento di parole duplicate). Quindi l'ho modificato solo con la mia osservazione per evitare di mettere altri problemi all'utente.
 
Ultima modifica:

tsle

Nuovo Utente
13
1
Salve a tutti,
grazie per i suggerimenti, ho cercato di attuarli ma sono un po' confuso. Ho provato perciò a semplificare. Ho cercato di scrivere il programma in modo che ogni parola immessa nella struttura si potesse anche ripetere ma se era uguale ad un' altra all' interno della struttura, il contatore corrispondente si sarebbe incrementato. Quindi senza eliminare le parole ripetute ma comunque sto sbagliando ad applicare strcmp e suppongo perchè sto confrontando due strutture e non due char, nonostante questo non so come risolvere il problema.

C:
#include <stdio.h>
#include <string.h>


int main(){
int i, s;
    

    
    struct insieme {
     char parola[26+1];
     int conta;
    };
    
    struct insieme frasi[10];
    
    printf("Inserisci le parole\n");
    
    for(i=0;i<10;i++){
      for(s=0;s<10;s++){
      
    scanf("%s", &frasi[i].parola);
    
   int strcmp(frasi[i].parola, frasi[i-s].parola);
  
   if(i=1 && strcmp(frasi[i].parola, frasi[i-s].parola) !=0){;}
       else{frasi[i].conta+1;}
     }
   }
    
    for(i=0;i<100;i++){

    printf("la parola: %s è ripetuta : %d", frasi[i].parola, frasi[i].conta);
    
   }   
return 0;   
    
}
 

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!