Newsgroup: it.comp.lang.c++
Titolo: Confrontare due parole

Ciao a tutti, mi chiamo Fulvio e ho appena iniziato a dare uno sguardo al
c++.
Mi servirebbe una mano a risolvere questo problema: come faccio a
confrontare due parole per sapere se usano lo stesso tipo e n° di lettere.
fino ad ora sono solo riuscito a contare quante lettere vi sono in una
parola, ma non ho trovato esempi per risolvere questo problema.
Grazie e saluti, Fulvio

confrontare due parole per sapere se usano lo stesso tipo e n° di lettere.
#include <iostream>
#include <string>
using namespace std ;
int main()
{ 
    string a = "ciao" ;
    string b = "miao" ;
    if ( a == b )
       cout << "le stringhe sono uguali" << endl ;
    else
       cout << "le stringhe sono differenti" << endl ;
    return 0 ;       
}
--
Andrea Laforgia (ICQ 87230455)
------------------------------ 
#exclude <windows.h>

 wrote in message
5btb3t4u3ou2pjhbq...@4ax.com...


di caratteri.
Credo che l'esempio seguente vada bene :
(non mi piace molto il fatto di non deallocare la memoria puntata,
fatemi sapere le valide alternative).
#include <iostream>
#include <string>
using namespace std ;
typedef int t_signature[ 256 ] ;
string&  get_signature( const string& s )
{
         string *t = new string ;
         t_signature signature = { 0 } ;
         for ( unsigned i = 0 ; i < s.length() ; i++ )
            ++signature[ s[i] ] ;
         for ( unsigned i = 0 ; i < 256 ; i++ )
             if ( signature[ i ] )
                *t += i ;
         return *t ;
}
bool check( string a, string b )
{
     return ( get_signature( a ) == get_signature( b ) ) ;
}
int main()
{
    string a = "lavagna" ;
    string b = "valanga" ;
    if ( check( a, b ) )
       cout << "le due stringhe usano le stesse lettere" << endl ;
    else
       cout << "le due stringhe NON usano le stesse lettere" << endl ;



--
Ivan Molella
__LINUX__ the choice of the __GNU__ generation
icq# 97960484

 fatemi sapere le valide alternative).
questa è una possibile alternativa
#include <string>
#include <iostream>
bool check(const std::string& s1, const std::string& s2)
{
  std::string::const_iterator it1, it2;
  it1 = s1.begin();
  it2 = s2.begin();
  while(*it1 || *it2 )
    {
      if(*it1 != *it2)
 {
   std::cout << " lettera sbagliata: " << *it2 << std::endl;
   return false;
 }
      ++it1;
      ++it2;
    }
  std::cout << "le parole sono uguali e contengono " << s1.size() << " lettere:
" << std::endl;
return true;
}
int main(int argc, char* argv[])
{
  std::string a = "valanghe";
  std::string b = "vaLanghe";
  std::cout << a << "\t \t" << b << std::endl;
  std::cout << check(a, b) << std::endl;
}

hai tempo fino a mezzanotte...;-)
poi la carrozza si ritrasforma in una zucca...
_snip_

> string  get_signature( const string& s )
Che scemo ! e' la cosa piu' naturale e non ci avevo pensato ! :)
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che
 sono bravi in matematica e quelli che non lo sono."

 fatemi sapere le valide alternative).  
Come alternativa si potrebbe trasformare il tuo get_signature e farlo
diventare il costruttore di una classe signature:
 class signature
 {
   std::string m_t;
   public:
   signature( const std::string& s ); 
   /* identico a get_signature() salvo che invece di *t usiamo m_t */
   bool operator==( const std::string& that ) const { return m_t==that.m_t; }
 };
Quindi check() diventa:
 bool check( string& a, string& b )
 {
      return ( signature( a ) == signature( b ) ) ;
 }
Max

 debitore.
Potresti definire un array di 26 elementi interi, uno per ogni lettera
dell'alfabeto, e scorrere la stringa andando ad incrementare l'intero
corrispondente. Alla fine avresti una rappresentazione confrontabile
delle due stringhe (basta confrontare i due array elemento per
elemento).
EMG

Saluti, Fulvio.
#include<string>
#include<iostream>
#include<algorithm>
bool comparestrings(std::string str1,std::string str2)
    {
    //Ordina le due stringhe,poi le confronta.
    sort(str1.begin(),str1.end());
    sort(str2.begin(),str2.end());
    return(str1==str2);
    }
int main()
    {
    //Prova!!
    std::string prima="ROMA";
    std::string seconda="AMOR";
    if(comparestrings(prima,seconda))
        std::cout<<prima<<"("<<prima.size()<<" car.) =
"<<seconda<<"("<<seconda.size()<<" car.)\n";
    else
        std::cout<<prima<<"("<<prima.size()<<" car.) !=
"<<seconda<<"("<<seconda.size()<<" car.)\n";
    return 0;
    }
Il Ghenio
-----
E'più oscuro del crepuscolo, é più rosso del sangue,
in nome della pace e della giustizia faccio appello a
tutti i poteri più remoti dell'oscurità, perché mi
aiutino a distruggere i miei nemici e tutti coloro
che saranno tanto sciocchi da ostacolarmi. FULMINE ROSSO!!
(Slayers)
-----

 wrote in message
RTlZ5.84802$hk4.3...@news.infostrada.it...


      ++signature[ s[i] ] ;
E chi ha detto che i caratteri non hanno segno ?
Un approccio che usi (un po' sprecando) la notevole
libreria standard C++ potrebbe essere il seguente:
////////////////////////////////////////////////////
  #include <iostream>
  #include <string>
  #include <set>
  #include <algorithm>
  bool StessiCaratteri(const std::string& s1,
                       const std::string& s2)
  {
    return std::set<char>(s1.begin(),s1.end())
           ==
           std::set<char>(s2.begin(),s2.end());
  }
  bool Anagramma(std::string s1,
                 std::string s2)
  {
    std::sort(s1.begin(),s1.end());
    std::sort(s2.begin(),s2.end());
    return s1 == s2;
  }
  int main()
  {
    std::string s[]={"ROMA","AMOR","RAMARRO"};
    for (int i=0; i<3; i++)
      for (int j=i+1; j<3; j++)
      {
        if (StessiCaratteri(s[i],s[j]))
          std::cout << "'" << s[i]
                    << "' ha gli stessi caratteri di '"
                    << s[j] << "'\n";
        if (Anagramma(s[i],s[j]))
          std::cout << "'" << s[i]
                    << "' e' un anagramma di '"
                    << s[j] << "'\n";
      }
    return 0;
  }
////////////////////////////////////////////////////
In teoria sort e set potrebbero non essere cosi'
terribili ma avere una specializzazione sui char
(es. con autosort o implementando un set<char>
con un array bitmapped).
(molto in teoria)
Che ne pensate ?
Andrea
--
Andrea Griffini, Programmer
http://www.netservers.com/~agriff

 Che scemo ! e' la cosa piu' naturale e non ci avevo pensato ! :)
...scusa, ma ritornare un reference a una variabile locale mi sembra
*MALE*...
Massimo

Non sara' elegantissimo, ma non bastava applicare std::sort alle
stringhe del tuo esempio precedente e rifare il confronto?
Ciao,
Nicola

*MALE*...
Mi pare che invece ritorni un valore.
Paolo

 wrote :

questo codice pero' non tiene in considerazione il fatto che una parola puo'
contenere caratteri uguali :
se fai string a = "lello" e string b="leo" la funzione check ritorna true.
Per rimediare la cosa piu' ovvia mi sembra quella di modificare il secondo
loop for in questo modo :
for ( unsigned i = 0 ; i < 256 ; i++ )
    for (int temp=0; temp < signature[ i ]; temp++)
        *t += i ;
ciao
Franz

 wrote in message
5btb3t4u3ou2pjhbq...@4ax.com...



Perchè non fai semplicemente un sort sulle stringhe e poi le
confronti con l'operatore== ?



Non ho capito bene il problema ma se il problema non riguarda il
numero delle lettere (quindi "ABC" e "ABCC" risolvono il problema)
basta l'algoritmo standard unique_copy su entrambe, poi un sort ed un
confronto. Se invece le due parole sono semplicemente l'una
l'anagramma dell'altra il tuo metodo mi sembra migliore.
Anto

Mi pare che invece ritorni un valore.
Ad ogni modo ho provato il suo algoritmo con le due stringhe
string a = "lavagna" ;
string b = "vvalanga" ;
e mi ha risposto
"le due stringhe usano le stesse lettere".


basta l'algoritmo standard unique_copy su entrambe, poi un sort ed un
Un appunto solo per ricordare che unique_copy richiede che la
sequenza sia ordinata in partenza. Quindi eventualmente *prima*
chiami sort e poi unique_copy (trovo che pero' la soluzione
std::set sia piu' elegante anche da un punto di vista filosofico)
HTH


"le due stringhe usano le stesse lettere".
Difatti e' giusto.


*MALE*...
Viene restituita una stringa per valore.
Nessun reference.


se fai string a = "lello" e string b="leo" la funzione check ritorna true.
"lello" e "leo" usano le stesse lettere, non vedo quale sia il
problema. E' chiaro che check restituisce true.
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che


+compatto......
bleah...
:)
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che


libreria standard C++ potrebbe essere il seguente:
Non conosco tutte le possibilita' della libreria standard, portate un
po' di pazienza ;)
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che


 wrote:

Probabilmente bastava, non sapevo della sua esistenza.
Come gia' ribadito, portate un po' di pazienza :)
--
Andrea Laforgia (ICQ 87230455)
"ci sono tre tipi di persone nel mondo : quelli che


 problema. E' chiaro che check restituisce true.
io avevo capito, come molti altri, che le 2 stringhe per essere uguali
dovessero avere le stesse lettere (e nello stesso numero), cioč che una
fosse l'anagramma dell'altra.
Pero' in effetti Fulvio aveva semplicemente chiesto di poter stabilire
quando 2 stringhe usano le stesse lettere e lo stesso numero di lettere.
Quindi "lello" != "leo", ma "caccc" == "cacca" (perdonatemi l'esempio ma non
mi viene altro...:)
ciao
Franz

l'anagramma dell'altra il tuo metodo mi sembra migliore.
Penso che la soluzione migliore sia quella da me postata tre sere fa,
che al limite potrebbe essere innestata all'interno di una classe ed
ottimizzata in modo che eviti la chiamata alla funzione comparestrings
(e quindi anche di eseguire il sort delle stringhe)e ritorni subito
false nei casi in cui il numero di caratteri delle due stringhe sia
differente.


mi viene altro...:)
Hmmm... a questo punto, quindi, basterebbe aggiungere il controllo che
le lunghezze delle stringhe corrispondano.


 le lunghezze delle stringhe corrispondano.
Non solo.  "aabb" e "aaab" hanno stessa lunghezza e stesse lettere, ma...
-- 
Maurizio Loreti                         
http://www.pd.infn.it/~loreti/mlo.html
Univ. of Padova, Dept. of Physics - Padova, Italy            
lor...@pd.infn.it
A C++ exception is when the code gets in trouble and says:
"Beam me up, Scotty!".

 Non solo.  "aabb" e "aaab" hanno stessa lunghezza e stesse lettere, ma...
Fulvio ha chiesto solamente che le 2 stringhe abbiano gli stessi caratteri e
lo stesso numero di caratteri
che poi forse intendesse dire che i caratteri devono essere presenti nello
stesso numero è un'altra cosa..:)
ciao
Franz

 Saluti, Fulvio.
Basta ordinare le stringhe e poi confrontarle:
#include <string>
#include <algorithm>
using namespace std;
int main( int argc, char **argv )
{
        if( argc < 3 ){ 
                cerr << "Pochi parametri" << endl;
                return 10;
        }
        string  s1(argv[1]),s2(argv[2]);
        sort( s1.begin(),s1.end( ) );
        sort( s2.begin(),s2.end( ) );
        cout << "s1 = "<<s1<<"; s2= "<<s2 <<endl;
        if( s1 == s2 )
                cout << "Le due parole contengo le stesse "
                        "lettere nella stessa quantita'" <<end;
        else
                cout << "Le due parole sono diverse" << endl;
}

 *MALE*...
Infatti non è scritto "string & get_signature(...)", nel qual caso si
tratterebbe di un reference. Invece in questo caso l'argomento viene
restituito per valore.
Domenico Barra

std::set sia piu' elegante anche da un punto di vista filosofico)
questo non lo sapevo; ecco quello che succede quando si studia troppa
teoria e si fa poca pratica...
Anto