Newsgroup: it.comp.lang.c++
Titolo: presenza valore in array

Ho una variabile di tipo intero e devo vedere se il suo valore č tra un 
gruppo di una decina di valori possibili
Mi serve per fare una cosa del tipo:
if (pippo in [12,33,56...]) then...
Attualmente faccio un for confrontando la variabile con gli elementi di un 
array dichiarato come int array[]={12, 33,66..}
C'č qualcosa di bell'e pronto tipo una clausola IN come per le query in Sql?
-- 
_________________________________________
Edmondo Di Tucci snar...@Tlibero.it
guarda i miei lavori su: 
www.powernetsi.it/edmondo
 


Ciao,
Si, c'è qualcosa di bell'e pronto nella Libreria Standard del C++. La prima
cosa che mi viene in mente è di copiare i valori campione dall'array in un
std::set<int> per poi cercare il valore che ti serve sapere se esiste
tramite il metodo find() il quale restituisce un iteratore con la posizione
dell'elemento oppure end() se non viene trovato.
Considera che è molto più efficente di cercare uno per uno nell'array,
perchè i "set" della Libreria Standard C++ sono di solito implementati come
"Red-Black Trees" e quindi le comparazioni per ricerca hanno complessità
logaritmica.
Ad esempio se hai un "set" con 100 numeri da confrontare la ricerca viene
effettuata con una media di 7 comparazioni, contro la media di 50
comparazioni che un'algoritmo dovrebbe effettuare su un array (sempre di 100
elementi).
Buon lavoro,
fabiomdf
--------------------------------
Inviato via 
http://arianna.libero.it/usenet/

 logaritmica.
[cut]
Per una decina di elementi non conviene utilizzare uno switch - case ?
-- 
Anche se detesto quello che dici,
difendero' fino alla morte il tuo diritto a dirlo.
   - Voltaire
/\/ / /-/ / /_   Copyleft (L) 1984, All Rights Reversed

 Per una decina di elementi non conviene utilizzare uno switch - case ?
Ciao,
Non avevo fatto caso che si trattasse solo di una decina di elementi.
Comunque non ti seguo: cosa c'entra lo switch-case con la ricerca in se?



Ah, scusa la mia mancanza di riflessi pronti. Ho capito cosa intendi anche
se non mi sembra la soluzione più pulita. Ma è una questione di stile,
immagino.
Saluti,


Se il tuo array e' ordinato puoi usare
std::binary_search(array, array + sizeof(array)/sizeof(int), valore)
che ritorna un bool. Altrimenti puoi usare allo stesso modo
std::find(), che ritorna un puntatore all'elemento se esiste, array +
sizeof(array)/sizeof(int) (ovvero un puntatore oltre l'ultimo elemento)
altrimenti.
Ciao,
Nicola

 Comunque non ti seguo: cosa c'entra lo switch-case con la ricerca in se?
Se Edmondo di Tucci si e' espresso bene, i possibili valori che la variabile 
(singola) puo' assumere sono soltanto una decina, quindi il metodo piu' 
efficace e veloce, IMHO, e':
int var = 0;
/* tante belle cose tra le quali la modifica del valore della variabile */
switch (var) {
case 0: [...] break;
case 1: [...] break;
[...]
case 9: [...] break;
[...]
}
Non sara' elegante, ma almeno non ho scomodato liste o alberi... :-)
ciao,
Paolo


Se hai letto il messaggio originale, questo corrisponderebbe a
scrivere:
bool trovato = false;
switch(var) {
case 12: case 33: case 56: /* altri casi */
trovato = true;
break;
}
if ( trovato )
...
Francamente trovo gia' meglio scrivere l'if esteso:
if ( var == 12 || var == 33 || var == 56 /* altri casi */ )
ed ancora di piu' le soluzioni basate su array se la sequenza e' fissa,
o contenitori se e' variabile.
Ciao,
Nicola


Hai ragione... non deve discriminare l'esecuzione secondo il valore assunto 
dalla variabile in questione, ma vuole solo sapere se 'va bene'.
Chissa' come ho fatto ad interpretare cosi' a membro di segugio? Mea culpa.

std::binary_search(array, array + sizeof(array)/sizeof(int), valore)
mi pare migliore, ci do un'occhiata e poi vi faccio sapere


Grazie alle vostre dritte ho trovato quello che più mi fa comodo ovvero:
  int ISDNCauseNoRichiama[] = {513,534,540};
    bool PuoiRichiamare=True;
    for (int i = 0; (i <
sizeof(ISDNCauseNoRichiama)/sizeof(ISDNCauseNoRichiama[0]))&&(PuoiRichiamare);
i++)
      PuoiRichiamare=(cp->ISDNCause != ISDNCauseNoRichiama[i]);
int trovato=0;
int ISDNCauseNoRichiama[] = {513,534,540};
std::count(vintageYears,
                vintageYears+(sizeof(ISDNCauseNoRichiama)/sizeof(ISDNCauseNoRichiama[0])),
               cp->ISDNCause ,
               trovato);
Ovviamnte trovato<>0 è quello che volevo


 std::count
Credo tu possa usare anche std::find.
-- 
[ RiK0                                ]
[ Go away! The internet is full!      ]
[ Non credo negli schemi non vincenti ]