Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 11
  1. #1
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    182

    [C++] anagramma e permutazione lettere in modo casuale

    Mi sono imbattuto in questo esercizio:

    Si scriva in C++ un programma completo opportunamente modularizzato in funzioni che, lette da input due parole di uguale lunghezza, verifichi se sono l’una anagramma dell’altra. Due parole sono una l’anagramma dell’altra se contengono le stesse lettere ma in ordine diverso. Esempio: La parola locandiera è un anagramma della parola calendario.
    Se le due parole non sono una l’anagramma dell’altra, si consideri la prima inserita da input e se ne costruisca un anagramma permutando in modo casuale le lettere di cui è composta (non importa se la parola ottenuta non è di senso compiuto). Esempio: se da input sono state inserite le parole casa e sala, si consideri la parola casa e si permutino in modo casuale le sue lettere. Dopo questo procedimento si potrebbe ad esempio ottenere la parola asca.

    Ho provato ad abbozzare le principali funzioni (per ora senza main..):
    codice:
    bool anagramma(char a[], int dim, chat b[], int dim){
                           for (int i=0; i<dim; i++){
                                                           for(int j=0; j<dim; j++)
                                                           if(a[i]==b[j])
                                                           return true;
                                          return false;
                                                           if(a[i]==b[i])
                                                           return false;
      }//for
    }
    
    
    void permuta(char a[], int dim){
                                                char c[];
                                                for(int i=0; a[i]!='\0'; i++){
                                                int casuale=1+rand()%dim;
                                                a[i]=c[casuale];
      }//for
    }
    Ho dubbi sulla prima funzione riguardo a:
    è il modo giusto per confrontare le lettere della parola contenuta nell'array a con quelle di b? Il for innestato permette di fare questo? cioè mi sa che va evitato di confrontare elemento per elemento come nel caso in cui si volesse verificare se la parola dell'array a fosse uguale a quella di b..mentre in questo caso vogliamo vedere solo se sono anagrammi!

    Sulla seconda funzione:
    Va bene per mescolare le lettere dell'array a e metterle in un nuovo array c in modo casuale?
    Il for è esatto?

    In questi casi è meglio usare string o char?

  2. #2

    Re: [C++] anagramma e permutazione lettere in modo casuale

    Originariamente inviato da mistergks
    Ho dubbi sulla prima funzione riguardo a:
    è il modo giusto per confrontare le lettere della parola contenuta nell'array a con quelle di b?
    A è anagramma di B se, A contiene tutti i caratteri in B ed ogni carattere occorre in A con la medesima frequenza riscontrata in B, quindi l'ordine non conta.

    Originariamente inviato da mistergks
    Sulla seconda funzione:
    Va bene per mescolare le lettere dell'array a e metterle in un nuovo array c in modo casuale?
    Si, però puoi farlo anche nello stesso array.

  3. #3
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    182
    quindi le funzioni che ho scritto vanno bene?!

  4. #4
    Entrambe le funzioni sono errate; la prima esce subito alla prima lettera che corrisponde, e comunque, se ho capito quello che avresti intenzione di fare (cercare nella seconda stringa ogni lettera della prima), l'approccio è errato, poiché dà risultati sbagliati in caso di alcune parole con doppie.
    Inoltre la funzione ha due parametri con il medesimo nome (dim), il che ovviamente non è consentito.

    Anche l'approccio della seconda è sbagliato, dato che, usando generici numeri casuali, nulla impedisce che lo stesso numero venga pescato più volte, ottenendo così un anagramma privo di alcune delle lettere della parola di partenza.

    Il metodo più semplice per vedere se due parole sono l'una l'anagramma dell'altra è di ordinarle entrambe in ordine alfabetico e poi confrontarle: se coincidono erano l'una l'anagramma dell'altra (per dirla in un altro modo, l'ordinamento riduce tutti gli anagrammi della medesima parola ad una rappresentazione comune univoca, che può essere quindi facilmente confrontata).
    Per quanto riguarda le permutazioni, ci sono diversi algoritmi "classici", ne trovi alcuni qui.

    Se ti è consentito usare le funzioni standard della STL, la libreria C++ fornisce sia la funzione sort che la next_permutation. Usandole in abbinata con le stringhe C++ il tuo problema si riduce ad una cosa semplicissima:
    codice:
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    bool VerificaAnagramma(string Str1, string Str2);
    string GeneraAnagramma(string Str);
    
    int main()
    {
        srand(time(NULL));
        string str1, str2;
        cout<<"Inserisci la prima parola: ";
        cin>>str1;
        cout<<"Inserisci la seconda parola: ";
        cin>>str2;
        if(str1.size()!=str2.size())
        {
            cout<<"Le due parole hanno lunghezze diverse."<<endl;
            return 0;
        }
        if(VerificaAnagramma(str1, str2))
        {
            cout<<"Le due parole sono l'una l'anagramma dell'altra."<<endl;
        }
        else
        {
            cout<<"Le due parole non sono l'una l'anagramma dell'altra.\n";
            cout<<"Un anagramma di "<<str1<<" e' "<<GeneraAnagramma(str1)<<endl;        
        }
        return 0;
    }
    
    bool VerificaAnagramma(string Str1, string Str2)
    {
        // ordina i caratteri delle stringhe
        sort(Str1.begin(), Str1.end());
        sort(Str2.begin(), Str2.end());
        // restituisce l'esito del confronto
        return Str1==Str2;
    }
    
    string GeneraAnagramma(string Str)
    {
        const int maxCicli=10; // massimo numero di permutazioni da scorrere
        // scorre un numero casuale di permutazioni
        int cicli=rand()%maxCicli;
        for(int i=0; i<cicli; i++)
            next_permutation(Str.begin(), Str.end());
        // restituisce l'ultima generata
        return Str;
    }
    Se comunque questo è un esercizio suppongo che lo scopo sia proprio quello di farti scrivere le funzioni di ordinamento e di permutazione.
    Amaro C++, il gusto pieno dell'undefined behavior.

  5. #5
    Originariamente inviato da mistergks
    quindi le funzioni che ho scritto vanno bene?!
    No, altrimenti non avrei risposto.

    Per quanto riguarda il primo problema, puoi trovare una soluzione che non ricorra all'ordinamento.

  6. #6
    Originariamente inviato da VincenzoTheBest
    Per quanto riguarda il primo problema, puoi trovare una soluzione che non ricorra all'ordinamento.
    L'unica che mi viene in mente "al volo" è O(n^2) contro O(n log n) del QuickSort...
    Amaro C++, il gusto pieno dell'undefined behavior.

  7. #7
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    182
    Grazie mille per le risposte!
    Beh da quel che ho capito... per la prima funzione..devo ordinare entrambe le stringhe in ordine alfabetico e poi logicamente se le due stringhe sono anagrammi dovrebbero essere uguali una volta ordinate alfabeticamente..
    Il mio problema ora è: con quale ordinamento? esiste un algoritmo generico? non so ordinare in ordine alfabetico! non mi viene nessuna idea in mente per poter farlo!

  8. #8
    Non vedo il problema... le stringhe di fatto sono array di char, e i char in effetti sono semplicemente dei numeri. Usa l'algoritmo di ordinamento che preferisci (un grande classico è il QuickSort) confrontando gli elementi con i normali operatori relazionali (<, >, ==).
    Amaro C++, il gusto pieno dell'undefined behavior.

  9. #9
    Utente di HTML.it
    Registrato dal
    Dec 2010
    Messaggi
    182
    il bubble sort non va bene?!
    Comunque il problema è che con in numeri si può fare per esempio if(3>2) con i char come faccio?! mica posso fare if(b<c) ?!? come faccio a stabilire l'ordine alfabetico?

  10. #10
    Originariamente inviato da mistergks
    il bubble sort non va bene?!
    Va bene un algoritmo di ordinamento qualunque.
    Comunque il problema è che con in numeri si può fare per esempio if(3>2) con i char come faccio?! mica posso fare if(b<c) ?!? come faccio a stabilire l'ordine alfabetico?
    Certo che puoi farlo; 'a'<'b' restituisce true. Come detto, i char non sono altro che un particolare tipo numerico, in cui ad ogni numero corrisponde una lettera; questa corrispondenza è ordinata (finché rimani sulle lettere senza accenti e sui numeri), per cui a lettera che viene prima nell'alfabeto corrisponde un numero minore.
    Amaro C++, il gusto pieno dell'undefined behavior.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.