Conta parole

di il
11 risposte

Conta parole

Ciao ragazzi,
ho un problema ed un blocco che mi attanaglia da più tempo.
Non riesco proprio a trovare una soluzione, o meglio, ne ho trovata qualcuna che mi convince decisamente al momento del debug risulta una cavolata..

La situazione è questa: ricevo un file di testo in input su più righe con tante lettere consecutive senza un significato logico. Ad esempio, una riga può risultare nel seguente modo:

dsajjdknfjsnadknjknigajbc

Mi viene chiesto di contare quante parole corrispondenti ad una data dal testo riesco a trovare in tutto il file. Ad esempio, per quanto riguarda la riga precedente, possiamo pensare di ricercare la parola "sanga". In quella riga ne risulta un, ovviamente dovendo unire lettere sparse per tutta la riga (e la mia difficoltà è appunto il gestire le lettere intermedie che a volte corrispondono anche alla lettera interessata, ma da scartare perchè doppiona, come nell'esempio potrebbe risultare più volte la "n").

Qualcuno riesce a darmi una mano?
E' un problema abbastanza stupido, lo so, ma per me difficilissimo da gestire..

11 Risposte

  • Re: Conta parole

    Salve.
    Guarda il funzionamento del mio codice e adattalo alle tue esigenze:
    
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
    	char str[50], parola[50];
    	int c = 0, np = 0;
    
    	printf("Inserire stringa dove ricercare la parola >> ");
    	scanf("%s", str);
    	printf("Inserire la parola da ricercare >> ");
    	scanf("%s", parola);
    
    	for(int i=0; i<strlen(str); i++)
    	{
    		if(str[i] == parola[c])
    		{
    			str[i] = '-';
    
    			if(c == strlen(parola)-1)
    			{
    				c = 0;
    				np++;
    			}
    			else
    			{
    				c++;
    			}
    
    			i=0;
    		}
    	}
    
    	printf("\nNumero parole trovate >> %d\n\n", np);
    
    	return 0;
    }
    
  • Re: Conta parole

    La prima soluzione che mi verrebbe in mente su due piedi sarebbe leggere il file una riga per volta, la riga buttarla in una stringa e analizzare quest'ultima: se appaiono tutti i caratteri (non hai specificato se devono essere anche nella stessa posizione, cioè se io cerco "qualcosa" e la riga è "uqalcosa" la parola è considerata trovata oppure no) allora aumenta il contatore delle corrispondenze e dopo aver fatto 'sta roba passa alla lettura della riga successiva, fino alla fine del file.
    (è una soluzione che mi è venuta in mente su due piedi senza scrivere nulla, controlla il codice di Wolt che magari è molto più sensato della mia idea).
  • Re: Conta parole

    In effetti forse mi sono spiegato male.
    Nelle mie intenzioni iniziali non ho specificato il fatto che le parole dovessero essere in sequenza, quindi "uqalcosa" non sarebbe stato come "qualcosa".
    Ed invece il codice del gentilissimo Wolt (che ringrazio molto) riconosce "uqualcosa" come "qualcosa", visto che viene etichettata come "-" solamente la lettera scoperta.

    Comunque grazie a questo mio errore, ho capito più o meno come sviluppare il codice (ora ci proverò, al limite vi romperò ancora! ) sia in un modo che nell'altro.
    In linea di principio, se sono da considerare solo le lettere in sequenze dovrei mettere "-" ad ogni lettera precedente a quella trovata, giusto?
    E' utile per me conoscere entrambi i modi per poi poter sviluppare entrambi gli algoritmi!
    Nel frattempo vi ringrazio entrambi
  • Re: Conta parole

    Mentre svilluppavo il programma ho riscontrato un'altra difficoltà che mi ero dimenticato di illustrare.
    Se considero il file riga per riga, rischio di perdermi una parola che ha un certo numero di lettere in due righe diverse. L'approccio per riga non mi sembra quindi il più adatto.
    Come faccio a considerare il file come se fosse consecutivo?
  • Re: Conta parole

    Simercole ha scritto:


    In linea di principio, se sono da considerare solo le lettere in sequenze dovrei mettere "-" ad ogni lettera precedente a quella trovata, giusto?
    Devi etichettare solo lettere che prendi per provare a formare la parola in quel momento.

    Simercole ha scritto:


    Se considero il file riga per riga, rischio di perdermi una parola che ha un certo numero di lettere in due righe diverse. L'approccio per riga non mi sembra quindi il più adatto.
    Come faccio a considerare il file come se fosse consecutivo?
    Questo dipende principalmente da quello che stai facendo. Potresti postare il codice?
  • Re: Conta parole

    Wolt ha scritto:


    Devi etichettare solo lettere che prendi per provare a formare la parola in quel momento.
    Si, hai ragione!
    Anche qui mi sono espresso male.
    Intendevo dire che per considerare le lettere consecutive non devo tornare indietro con l'indice i ma andare sempre avanti

    Wolt ha scritto:


    Questo dipende principalmente da quello che stai facendo. Potresti postare il codice?
    Ho preso spunto dal tuo codice. Però ripeto, persiste il problema che non considera elementi di righe diverse.
    Se il mio File è così composto:
    "si
    mo
    ne"
    analizzando riga per riga non troverà mai la parola "simone"

    ---
    
    while (fgets(str, DIMENSIONE, File) != NULL)
        {
            for (i = 0; i <= strlen(str); i++)
            {
                if (str[i] == parola[c])
                {
                    if (c == strlen(parola)-1)
                    {
                        c = 0;
                        NumeroParola++;
                    }
                    else
                        c++;
                }
                i++;
            }
        }
    
    Ho pensato però ad una possibile soluzione: come tu hai messo il controllo sulla fine della parola, potrei mettere anche il controllo sulla fine della riga e caricare la successiva tenendo ancora l'indice "c" della parola sulla lettera da trovare e riportando i = 0 per analizzare la riga.
    Solo che, come gli dico "Se l'elemento i è l'ultimo, carica nuova riga" essendoci un while fuori che caricare le righe?
    Spero di essermi fatto capire..
  • Re: Conta parole

    Hai vari modi per risolvere questo problema:
    - O utilizzi fread (http://en.cppreference.com/w/c/io/frea).
    - Oppure devi "assemblare" il testo completo con combinazioni di fgets e strcat (http://en.cppreference.com/w/c/string/byte/strca) e poi iniziare la ricerca.
  • Re: Conta parole

    Wolt ha scritto:


    Hai vari modi per risolvere questo problema:
    - O utilizzi fread (http://en.cppreference.com/w/c/io/frea).
    - Oppure devi "assemblare" il testo completo con combinazioni di fgets e strcat (http://en.cppreference.com/w/c/string/byte/strca) e poi iniziare la ricerca.
    Non conosco "fread" ora la studio.
    Per quanto riguarda strcat, è utile, ma se il testo è lunghissimo, non sapendo di quanti caratteri è formato, non riesco a stabilire una lunghezza adatta alla stringa per contenere tutti i caratteri in sequenza..

    Domanda: se utilizzassi una matrice di caratteri?
  • Re: Conta parole

    Ok, ho provato con una matrice di caratteri e sembra funzionare.
    Ho fatto una prova con il seguente testo cercando la parola "simone" e mi ha trovato due occorrenze (inizialmente il testo era composto dalle sole prime 4 righe e ne aveva trovata giustamente una sola).

    anso
    ifhm
    idma
    omne
    sudo
    snde
    inrt
    mnfe
    iros
    cgrn
    poir
    hgen

    Il codice è il seguente:
    
       while (fgets(str, DIMENSIONE, File) != NULL)
        {
            k = 0;
            for (j = 0; j <= strlen(str); j++)
            {
                Matrix[i][j] = str[k];
                k++;
                if (Matrix[i][j] == parola[c])
                {
                    if (c == strlen(parola)-1)
                    {
                        c = 0;
                        NumeroParola++;
                    }
                    else
                    {
                        c++;
                    }
                }
            }
            i++;
        }
    
    Sembra funzionare. Voi trovate qualcosa che non va?
  • Re: Conta parole

    Potresti risolvere anche così:
    
    #include <stdio.h>
    #include <string.h>
    
    int main()
    {
        char str[50], parola[30];
        int c = 0, np = 0;
        FILE *File = fopen("./p.txt", "r");
    
        printf ("Inserire la parola da ricercare nel file >> ");
        scanf("%s", parola);
    
        while(fgets(str, 50, File) != NULL)
    	{
    	   for(int i=0; i<strlen(str); i++)
    	   {
    	      if(str[i] == parola[c])
    	      {
    	         str[i] = '-';
    	
    	         if(c == strlen(parola)-1)
    	         {
    	            c = 0;
    				fseek(File, 0, SEEK_CUR);
    	            np++;
    	         }
    	         else
    	         {
    	            c++;
    	         }
    	
    	         i=0;
    	      }
    	   }
    	}
    
       printf("\nNumero parole trovate >> %d\n\n", np);
    
       return 0;
    }
    
  • Re: Conta parole

    Ah scusa, credevo che la parola fosse su una sola riga.
    allora se così non è potresti buttare tutto il file in una mega stringa che controllerai carattere per carattere.
    for (int i = 0; i < strlen (stringaFile); i++)
    {
        if (stringaFile[i] == key[j])
            j++;
    
        if (j == strlen (key))
        {
            j = 0;
            contaParole++;
        }
    }
    dove j è il contatore che ti indica fino a quale lettera della parola da cercare (key) sei arrivato a leggere e quando ha letto tutti i caratteri di quest'ultima, resetta questo contatore e aumenta di 1 il contatore delle parole trovate.
    unico svantaggio: se cerci "ciao" in un mare di 800 caratteri quest'algoritmo impiega molto tempo, ma essendo stringaFile non ordinata non ho idea di come ottimizzare la ricerca sinceramente...
Devi accedere o registrarti per scrivere nel forum
11 risposte