Newsgroup: it.comp.lang.delphi
Titolo: Numero di elementi di un insieme e velocità.

Ciao a tutti,
se ho un insieme cosi definito:
Type X: Set Of Byte;
Io so l'insieme X pu� contenere da un minimo 0 elementi (insieme vuoto) fino 
ad un massimo di 255 elementi.
Ora per determinare il numero di elementi di un insieme ho utilizzato questa 
funzione:
  Function TIdv.GeTElementsNumber (Ins: X): Byte;
    Var X, Y: Byte;
    Begin
      X := 0;
      For Y := 0 To 255 Do
        Begin
          If Y In Ins Then Inc (X);
        End;
      Result := X;
    End;
Che svolge egregiamente il suo compito; purtroppo per� in un contesto dove 
viene richiamata migliaia di volte, essa rallenta la velocit� di 
elaborazione dei dati, in conseguenza di ci� cercavo una soluzione 
alternativa e di conseguenza pi� veloce.
Sapete indicarmi una soluzione alternativa che mi fornisca l'informazione 
richiesta (il numero di elementi) in modo pi� veloce, senza ricorrere ad un 
ciclo?
Grazie in anticipo.
Cooper.
 

 Cooper.
Non l'ho mai provato, ma stando a quello che c'ï¿œ scritto qui: 
http://www.delphibasics.co.uk/RTL.asp?Name=Set
dovrebbe andar bene "X:=SizeOf(Ins)"
Ciao, Mario

 dovrebbe andar bene "X:=SizeOf(Ins)"
Come non detto, non ï¿œ quello che volevi tu ...
Ciao, Mario

 senza ricorrere ad un ciclo?
Temo che non vi sia una soluzione alternativa a quella che hai adottato 
tu; cercando in giro, ho individuato un codice che probabilmente 
velocizza l'operazione ottimizzando la verifica dei singoli byte della 
variabile che rappresenta il *set*:
http://codecentral.embarcadero.com/Item/14018
Personalmente, non mi � mai capitato di dover effettuare un simile 
conteggio su una variabile di tipo *set*... sei sicuro che questo tipo 
di variabile sia realmente adatto alla tua esigenza e che non sia invece 
pi� proficuo usare una struttura diversa, come un *array* o ancora 
meglio una *TList*?
Ciao,
   Marco.
-- 
MARCO BREVEGLIERI
  (
http://www.marco.breveglieri.name
)

    Marco.
In alternativa, potresti creare una struttura composta in questa 
maniera:
- totale elementi
- set
In fase di creazione il set ï¿œ vuoto ed il totale degli elementi ï¿œ 0. 
Quando aggiungi un elemento al set, incrementi il totale.
Quando togli un elemento dal set, decrementi il totale.
Se inizializzi il set azzeri il totale.
In questo modo, quando vuoi conoscere il numero degli elementi, ti 
basta testare il campo del totale.
Ciao, Mario

 ha scritto nel messaggio 
news:mn.14317da15...@libero.it...

Avevo pensato a una soluzione del genere, creando una classe che simulasse 
un insieme e le operazioni ad esso connesse (unione, intersezione etc)  ma 
poi facendo quattro conti l'ho scartata, nel senso che il numero di 
istruzioni eseguite diventa superiore a quelle della soluzione precedente.
Il mio obiettivo ï¿œ velocizzare il processo di elaborazione per "grandi 
numeri"; in questo modo mi trovo costretto a monitorare l'insieme facendo in 
ogni caso delle assegnazioni quando poi non mi servirebbero.
Invece ho risolto il problema riscrivendo l'algoritmo, e passando da circa 3 
minuti di "attesa" per l'elaborazione a circa 1 minuto e 20 secondi, circa 
20-30 secondi in piï¿œ rispetto allo stesso algoritmo escludendo il conteggio 
degli elementi.
Insomma sono riuscito comunque a dimezzare i tempi di elaborazione e giï¿œ ï¿œ 
qualcosa.
 

 numeri";
Che vuol dire "grandi numeri"? Quantifica.
A.


Significa che ci sono cicli che vengono eseguiti che nel TOTALE vengono 
eseguiti nell'ordine 8 zeri.; non c'� un ciclo con otto zeri, ma diversi 
cicli annidati che portano a quell'ordine di grandezza; non potendo quindi 
togliere quelli pi� esterni potevo agire su quelli pi� interni tipo 
l'esempio della funzione postata precedentemente.
 

 togliere quelli più esterni potevo agire su quelli più interni tipo



Non proprio permutazioni ma dei calcoli statistici; pi� precisamente 
parliamo di combinazioni.
 

 parliamo di combinazioni.
e non esiste qualche algoritmo che fa combinazioni senza cicli
annidati?
Mi sembra strano...Se ti basi sul n di elementi non potrai mai
generalizzare.
A.


Infatti io non mi baso sugli n elementi.
 

[...]
Le soluzioni piï¿œ semplici sono quelle migliori... :)
Non ci avevo nemmeno pensato... siamo messi bene... ;)


 simulasse un insieme e le operazioni ad esso connesse [...]
Non ï¿œ questo ciï¿œ che ti ï¿œ stato suggerito, nel senso che non ti ï¿œ stato 
suggerito di sostituire il set con altro, ma di inglobarlo all'interno 
di una struttura che contenga e gestisca anche le informazioni 
accessorie di cui hai bisogno, come il numero di elementi presenti 
nell'insieme, ovviamente evitando l'accesso diretto al campo privato che 
rappresenta proprio l'insieme.


> Non ci avevo nemmeno pensato... siamo messi bene... ;)
Su, Marco, su...
Sono i postumi delle megamangiate di queste festivita'.... :-D
A.

 ad un massimo di 255 elementi.
Se l'insieme su cui lavori � fisso, una buona soluzione � la seguente:
var
  S: set of char;
  SetBytes: array [0..Sizeof(S)-1] of Byte absolute S;
  I, J, ByteCard: Cardinal;
begin
  S:= ['a','b','c'];
  ByteCard := 0;
  for I := Low(SetBytes) to High(SetBytes) do
    for J := 0 to 7 do
      Inc(ByteCard, (SetBytes[I] shr J) and 1);
...
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it


Provo.  Non avevo pensato agli operatori logici, una soluzione cosi mi era 
tornata utile in passato per calcolare il binario di un numero usando 
l'operatore shr.
 

 l'operatore shr.
In realt� puoi anche fare a meno del secondo ciclo, esplicitando gli shift
per ogni posizione.
