Trovare parola minima e massima in un array di stringhe

di il
5 risposte

Trovare parola minima e massima in un array di stringhe

Buongiorno,
in un esercizio universitario devo risolvere il seguente problema:

Scrivete una funzione con prototipo
void smallest_largest( char *s[], int n, char **smallest, char **largest )
che, dato un array s lungo n di stringhe, trovi gli elementi minimo e massimo nell’array (secondo l’ordine alfabetico) e memorizzi gli indirizzi delle loro posizioni nel vettore s negli indirizzi di memoria puntati rispettivamente da smallest e da largest.

Nel cercare di risolvere l'esercizio, tuttavia, ho difficoltà ad assegnare correttamente l'indirizzo delle due parole ai rispettivi puntatori. Mi è anche sorto il dubbio che ci sia un errore nel testo, perché i due elementi smallest e largest sono semplicemente la parola più piccola e più grande, quindi una sola stringa, non dovrebbe servire un array frastagliato, dovrebbe bastare un puntatore a char.

Per memorizzare l'indirizzo della parola più piccola, una volta trovata, uso l'istruzione
*smallest = s, dove s è la stringa nell'array frastagliato (così facendo dovrei memorizzare direttamente l'indirizzo nel puntatore), idem per il massimo. Non capisco cosa non funzioni.

Di seguito il codice

#include "stdio.h"
#include "stdlib.h"
#include "ctype.h"
#include "string.h"

void smallest_largest( char *s[], int n, char **smallest, char **largest ) {
  for(int i=0; i<n; i++) {
    char *p1 = s[i];
    int j;
    for(j=i+1; j<n; j++) {
      char *p2 = s[j];
      if(strcmp(p1, p2) > 0) {
        break;
      }
    }
    if(j==n) {
      *smallest = s[i];
      break;
    }
    for(j=i+1; j<n; j++) {
      char *p2 = s[j];
      if(strcmp(p1, p2) < 0) {
        break;
      }
    }
    if(j==n) {
      *largest = s[i];
      break;
    }
  }
}

int main( int argc, char *argv[] ) {
    char* dict [] = { " ciao " , " mondo " , " come " , " aaa " , " bene " , " il " , " programma " };
    int lun = 7;
    char **smallest;
    char **largest;
    smallest_largest(dict, lun, smallest, largest);
    printf("Parola minima: %s\nParola massima: %s\n", *smallest, *largest);
    return 0;
}
Se qualcuno mi sa offrire il suo aiuto gli e ne sarei grato.

5 Risposte

  • Re: Trovare parola minima e massima in un array di stringhe

    Come hai cercato minimo e massimo? Sei sicuro che il metodo sua corretto? Ce lo commenti?
  • Re: Trovare parola minima e massima in un array di stringhe

    Allora per cercarli scorro l'array di stringhe con un ciclo for e poi ho due cicli for interni che partono da quella stringa e controllano tutte le successive per vedere se ce n'è una più lunga o una più corta (nel caso del minimo). Se quest'ultima viene trovata significa che quella che sto analizzando è da scartare perché ce n'è una più lunga (o più corta), quindi passo alla successiva e ripeto il procedimento finchè non trovo quella che è effettivamente la più corta e la più lunga. Per confrontare le stringhe utilizzo la funzione strcmp della libreria string.h. Il metodo dovrebbe essere corretto anche perché l'ho utilizzato per un programma precedente che però doveva restituirmi solo l'indice della parola più piccola.

    Tra l'altro mi sono dimenticato di dire che l'errore che ho avuto in fase di esecuzione è un errore di segmentazione, e la cosa strana che ho notato ora è che se imposto solo la parte per trovare il minimo tutto funziona, tuttavia non riesco a trovare cosa c'è che non va.
  • Re: Trovare parola minima e massima in un array di stringhe

    Penso di avere risolto proprio in questo momento, il problema è dovuto ad un break che mi interrompe il ciclo esterno dopo aver trovato il minimo e prima di trovare il massimo.

    L'errore di segmentazione probabilmente è dovuto al fatto che il secondo puntatore (**largest) non è inizializzato credo.

    Ringrazio comunque per l'aiuto.
  • Re: Trovare parola minima e massima in un array di stringhe

    Innanzitutto se hai una stringa (quindi char *) e vuoi modificarla in una funzione, allora utilizzi un char **.
    A quanto comprendo vuoi avere smallest e biggest non come copie, ma come puntatori ad elementi dell’array. Ok, ma char ** non è comunque il tipo corretto. Devi utilizzare char * e inizializzali a NULL, è buona pratica.

    Allora gli argomenti della funzione devono essere, come correttamente hai fatto, char ** poiché vuoi modificare dei puntatori.

    Quindi: [CODE] void smallest_largest(char *[], int, char **smallest, char **largest) { ... } int main(void) { ... char *smallest = NULL; char *largest = NULL; smallest_largest(dict, &smallest, &largest); ... } Ora non dovresti avere più problemi di segmentazione.

    Quello che devi fare nella tua funzione di ricerca del minimo e massimo è iterare nel vettore una ed una sola volta. Se l’elemento corrente è maggiore dell’elemento che consideri come maggiore, allora aggiorni l’indice; stessa cosa per quello minore. Alla fine dai i valori a smallest e biggest grazie agli indici che hai memorizzato.
    Algoritmo lineare.
  • Re: Trovare parola minima e massima in un array di stringhe

    Grazie per la risposta.

    Si in effetti mi sono accorto che non era una bella funzione e l'ho rifatta da 0 come hai poi detto anche tu (anche perché non era comunque corretta).

    Poi il mio problema è che faccio ancora un po' di confusione con gli array frastagliati e ci devo pensare un po' su: alla fine l'argomento della funzione deve essere un puntatore doppio semplicemente perché deve contenere l'indirizzo di un altro puntatore se ho ben capito.

    Io invece stavo ragionando in un altro senso e infatti non riuscivo a capire come mai servisse un puntatore doppio per contenere una sola stringa.

    I puntatori doppi dichiarati nel main sono un'altra cosa che stavo sbagliando infatti.

    Grazie ancora, e buona serata a tutti!
Devi accedere o registrarti per scrivere nel forum
5 risposte