Newsgroup: it.comp.lang.delphi
Titolo: Aiuto su Array

Qualche tempo fa avevo chiesto aiuto per sostituire
 
le clausole IN e INCLUDE dei SET Delphi
 
adattandole invece agli Array,gentilmente
 
mi era postato il codice di cui sotto
 
che con il tempo ho fatto funzionare perfettamente.
 
Contains=IN SetBit=INCLUDE
 
Il problema è che ho poi visto che in presenza di numeri duplicati
 
la procedura SetBit non mi inserisce i duplicati che invece a me servono
 
(Oppure è la funzione Contains che invece non mi legge i duplicati??)
 
Per chiarezza gli elementi del mio insieme sono numeri da 1 a N (non 0 a N).
 
Avendo una sequenza 6-3-1-4-4 uno dei due 4 non viene preso in 
considerazione
 
?
 
Vi chiedo se mi potete aiutare ancora una volta.
 
Grazie
 
Voltolini Luigi
 
?
 
?
 
?
 
?
 
Risposta data a suo tempo:
 
Se gli elementi del tuo insieme sono i numeri da 0 a N, puoi usare il metodo
 
usato di solito in C: consiste nell'usare array di Byte e di usare gli 
operatori sui bit (or e shift) per agire sugli elementi dell'insieme,
 
qualcosa di questo genere:
 
// non compilato, tanto meno testato!
 
type
 
TMySet = array[0..63] of Byte; // 86 byte = 512 bit
 
function Contains( const S : TMyset; bit : integer ) : boolean;
 
begin
 
Result := (S[ bit div 8 ] and (1 shr (bit mod 8) )) <> 0;
 
end;
 
procedure SetBit( var S : TMyset; bit : integer );
 
begin
 
S[ bit div 8 ] := S[ bit div 8 ] or (1 shr (bit mod 8) );
 
end;
 
 

 considerazione
 
OK. Quindi hai bisogno anche di memorizzare la sequenza dei numeri
(altra cosa che in un insieme non e' gestita)
 
A questo punto penso proprio che sia sbagliato usare l'insieme come
struttura dati. Ti conviene usare una lista.
 
Nella lista puoi usare Add per aggiungere un elemento, Remove per
toglierlo e IndexOf per sapere se un dato elemento e' nella lista.
Facendo un for da 0 a Count-1 puoi elencare tutti gli elementi
uno per uno.
 
Se hai delphi >= 2009 puoi usare la versione TList<Integer> 
 
altrimenti puoi provare a usare TList facendo ogni volta il
cast da integer a pointer e viceversa:
 
list.Add( pointer(1) ); 
if list.IndexOf( pointer(4) ) <> -1 then ...
 
eccetera.
 
Trattandosi di una cosa scomoda e anche potenzialmente fonte
di casini, ti consiglio di crearti una classe apposita
che implementa questo comportamento esponendo gia' i metodi
che gestiscono dati di tipo integer invece di pointer
 
ciao
Giacomo

<Questo temo che sia perche' i SET sono gli insiemi usati anche in 
matematica:
 
non hanno il concetto di elemento presente piu' volte.>
 
Ti ringrazio per la tua gentile risposta
 
cercherò di risolvere anche se sarà dura.
 
Dici che la colpa è dei SET,però il codice di cui sotto che mi avevi postato
 
qualche anno fa non fa riferimento ai SET,ma agli array!
 
Credevo che usando la procedura SetBit mi inserisse anche i duplicati.
 
Ti volevo chieder ancora una cosa,è possibile in qualche modo visualizzare 
in un TEdit
 
il contenuto di TMyset?
 
Grazie di nuovo
 
Voltolini Luigi
 
?


 Credevo che usando la procedura SetBit mi inserisse anche i duplicati.
 
Come fa a gestirti dei duplicati, se e` un bit, che puo` assumere valori 0 o 1?

Ciao,
  mi ricordo di una conversazione simile fatta qualche mese (anno?) fa.
Comunque sia lavorare con gli array non e' poi cosi' complicato (per come li 
usavo/uso).
Come ti e' stato gia' suggerito una valida alternativa e' data della TList 
che ha gia' tutto fatto e pronto per inserire, leggere, modificare, cercare, 
duplicare ecc... gli elementi che intendi inserire.
Se invece, per qualunque motivo, sei costretto ad utilizzare gli array i 
problemi sono pochi o nulli.
Dai un'occhiata qui per avere piu' informazioni
 
http://www.delphibasics.co.uk/RTL.asp?Name=array
 
http://delphi.about.com/od/beginners/a/arrays.htm
 
 
Ciao
 
Daniele
 

 Credevo che usando la procedura SetBit mi inserisse anche i duplicati.
 
Beh certo che no... una volta che il bit e' a 1 non e' che puo' andare a 2
quando inserisci il duplicato... :-o
 
Potresti provare a modificare il codice gestendo l'array dimensionandolo
in base agli elementi del tuo insieme e poi ogni elemento indica quante
volte e' stato inserito nella tua struttura dati. 
 
In questo caso, Contains diventa "if S[ i ] > 0" e SetBit
diventa "S[i] := S[i] + 1"
 
ciao
Giacomo
 
 

> Il problema è che ho poi visto che in presenza di numeri duplicati
 
E' inutile girarci attorno: devi cambiare la struttura dati.
 
 
A.

 E' inutile girarci attorno: devi cambiare la struttura dati.
 
In origine lui aveva definito
 
TMySet = array[0..63] of Byte;
 
In un byte puoi mettere numeri da 0..255, quindi (in teoria) potrebbe 
mettere anche 64 numeri uguali.
So che tu faresti in altro modo, ma se deve usare quell'array deve solo 
cambiare il modo di impostarlo e leggerlo.
 
Cosa dici ??
 
Ciao e buona settimana
 
Daniele 
 

> Cosa dici ??
 
Dico che sta girando attorno a questa cosa e ogni volta, pur di risparmiare, non bada a spese per evitare un re factoring.
 
A.