Newsgroup: it.comp.lang.visual-basic
Titolo: Passare matrice di integer ad una funzione

Eccovi il mio periodico post di richiesta aiuto. Allora, dallo studio dei
precedenti post ho capito che non posso fare una cosa del genere: matrice1()
= matrice() (fonte F1 e google), ci vuole una variabile variant o assegnare
i valori uno per volta (fonte:F1).
La questione č che devo passare una matrice di interi ad una function per un
bel "bubble sort" per farmela restituire ordinata, ma non riesco a trovare
una soluzione. Come posso fare? Avete altre (fonti)? spero di essere stato
chiaro. Grazie e ciao, SK

 bel "bubble sort" [...]
Usa qualsiasi cosa, ma non il bubble sort.
Se vuoi, proprio per matrici di long, ho scritto un algoritmo estremamente
performante (si basa sulla rappresentazione binaria). Lo scotto č che
funziona solo su interi o long e solo se sono tutti positivi.
x:termoPilucco.

 una soluzione.
Puoi restituirlo come risultato di funzione, per quanto detto sopra, ma dato
potresti applicare la funzione anche ad array molto grossi, e' piu'
efficiente evitare la copia e passare invece l'array per riferimento:
Private Sub BubbleSort(ByRef ArrayToSort() As Integer)
'...
End Sub
Ciao
-- 
Luca Dormio - 
luca....@tin.it
________________________________
"Marty, non stai ragionando in maniera quadridimensionale"
Dr. Emmett L. Brown

 funziona solo su interi o long e solo se sono tutti positivi.
Vorrei, saresti cosě gentile da postarlo o magari inviarmelo in allegato? il
mio @dd č corretto.
Grazie, SK

Il 24/09/2003 17.01, SpecialKeta scrisse:

Qui trovi teoria e pratica dell'ordinamento. E' in C, ma facilmente 
traducibile. Capitolo 8. Se cerchi con google poi dovresti trovare kili 
di codice VB per ordinare.
http://www.library.cornell.edu/nr/bookcpdf.html
ciao
	maxx
-- 
NOSPAM: Rimuovere i trattini dallo username!
Cut hyphens from my username!

 Vorrei, saresti così gentile da postarlo o magari inviarmelo in allegato?
il
[56K Alert] so che è troppo tardi :)
Tieni conto che ho scritto il tutto tempo fa e l'ho testato quanto
possibile, ma, ovviamente, non garantisco che funzioni in tutte le
circostanze.
Copia tutto ciò che segue in .bas, poi puoi usare sortarrbin per ordinare un
array.
Ricordati i prerequisiti: array di long non negativi.
Option Explicit
Public duealla() As Long ' array d'appoggio
Sub sortarrbin(v() As Long)
' Ordina array.
' Prerequisiti:
' L'array è di un tipo numerico intero (niente variant ne' virgola mobile)
' L'array non contiene valori negativi
Dim mx As Long ' massimo valore
Dim a As Long  ' per cicli
Dim lmx As Long ' bit necessari per rappresentare il valore
' tabella d'appoggio delle potenze di due
ReDim duealla(0 To 31) As Long
For a = 0 To 30
    duealla(a) = 2 ^ a
Next
' l'ultimo elemento della tabella va messo in questa notazione per non
' generare Overflow
duealla(31) = &H80000000
' cerco il massimo valore contenuto nell'array
mx = v(0)
For a = LBound(v()) To UBound(v())
    If v(a) > mx Then
        mx = v(a)
    End If
Next
' calcolo quanti bit sono necessari per rappresentare il valore massimo
lmx = cifrebinarie((mx))
' chiamo la routine di ordinamento su tutto l'array
Call sortbit(v(), lmx - 1, LBound(v), UBound(v))
End Sub
Function cifrebinarie(lng As Long) As Long
' numero di cifre binarie necessarie per rappresentare
' il numero intero non negativo passato
Dim dbl As Double
If lng < 1 Then
    cifrebinarie = 1
    Exit Function
End If
dbl = Log(lng) / Log(2)
cifrebinarie = Int(dbl) + 1
End Function
Sub sortbit(v() As Long, ByVal l As Long, ByVal st As Long, ByVal en As
Long)
' Nell'intervallo di elementi che vanno dalla posizione st alla posizione en
' separa quelli che hanno il bit più significativo a 1 da quelli che lo
' hanno a zero
' poi richiama se stesso nei due intervalli
Dim bitSignificativo As Long ' bit più significativo nell'intervallo in
esame:
Dim tmpV As Long             ' valore d'appoggio
Dim a As Long                ' contatore
Dim strmv As Long            ' numero elementi spostati
strmv = 0
bitSignificativo = duealla(l)
For a = st To en
    If (v(a) And bitSignificativo) <> 0 Then
        ' l'elemento attuale ha il bit significativo a 1:
        ' Lo metto in fondo, insieme agli altri con la stesa caratteristica
        If a <> en - strmv Then
            tmpV = v(a)
            v(a) = v(en - strmv)
            v(en - strmv) = tmpV
            ' segno che un nuovo elemento è stato spostato
            strmv = strmv + 1
            ' torno indietro nel ciclo for: avendo fatto una permutazione
            ' mi trovo nella posizione attuale un elemento ancora da
            ' analizzare
            a = a - 1
        End If
    End If
    ' verfico se è il caso di uiscire dal ciclo for e se l'ulimo elemento
    ' deve essere spsostato (in questo caso virtualmente, in quanto è già a
    ' cavallo dei due insiemi)
    If a = en - strmv Then
        If a >= 0 Then
            If (v(a) And bitSignificativo) <> 0 Then
                strmv = strmv + 1
            End If
        End If
        Exit For
    End If
Next
' chiamo ricorsivamente la sub sui due sottoinsiemi creati
' ma utilizzo un bit meno siginficativo per i confronti.
If l > 0 Then
    If strmv - 1 > 0 Then
        Call sortbit(v(), l - 1, en + 1 - strmv, en)
    End If
    If (en - strmv) - st > 0 Then
        Call sortbit(v(), l - 1, st, en - strmv)
    End If
End If
End Sub
' x:termoPilucco, casomai finissi nel .bas

 
http://www.library.cornell.edu/nr/bookcpdf.html
A proposito, qualcuno ne ha uno in VB spaventosamente veloce?
Mi piacerebbe misurare le prestazioni rispetto a quello che ho scritto.
x:termoPilucco.

 Ricordati i prerequisiti: array di long non negativi.
<Dato un taglio>
Grazie mille, non lo ho ancora guardato, solo voracemente copiaincollato su
txt.
Finirai nel .bas, prometto! anche se non so se ti piacerà.
Grazie ancora, SK

 scritto.
Provato con un quicksort?

 Provato con un quicksort?
Ho provato un Heap Sort (prestazioni analoghe a QS).
Tra l'altro, essendo VB di alto livello, molto dipende dall'implementazione
più che dall'algoritmo  (anche se ovviamente per array grandi prevale
l'algoritmo)
x:termoPilucco.

 ha scritto nel messaggio
news:bkscdt$5946q$1...@ID-188026.news.uni-berlin.de...

Con qualche piccola ottimizzazione, ho incluso il tuo algoritmo in un
progetto di esempio che tengo sempre sotto mano; direi che se la cava molto
bene, si gioca da vicino la prima piazza con Shell Sort e Quick Sort
(perlomeno nelle implementazioni che ho usato)
E' un po' lungo da postare qui, se ti interessa fai un fischio e te lo mando
in mail


 Mi piacerebbe misurare le prestazioni rispetto a quello che ho scritto.
Io ho leggermente rivisto l'algoritmo di quicksort2 presente sul sito 
comune.
Se ti interessa appena riesco a rimontare il mio PC te lo invio.
Ciao

 in mail
uh.. che bella idea.
[Include:  termoPilucco/fischio.wav]
Il mio indirizzo è il mio nick presso hotmail (adesso cominciano a fioccare
virus :) )
grazie,
termoPilucco

 Se ti interessa appena riesco a rimontare il mio PC te lo invio.
Sě, grazie anche a te.
Il mio indirizzo č il mio nick presso hotmail
termoPilucco

(perlomeno nelle implementazioni che ho usato)
Arrivato e testato:
Prendo un po' di mazzate dal Quicksort :(
Ma ti assicuro che se fosse possibile creare array di oltre 2 miliardi di
elementi le mazzate le prenderebbe lui :)
x:termoPilucco, in teoria.

Con qualche piccola ottimizzazione, ho incluso il tuo algoritmo [...]
Dimenticavo... grazie per il progettino.
x:termoPilucco

 Prendo un po' di mazzate dal Quicksort :(
In compenso ho scritto un nuovo algoritmo.
Si basa sul fatto che, spesso, il massimo elemento dell'array da ordinare ha
un valore non troppo alto.
In tali condizioni è circa 3 volte più veloce del precedente, in caso
contrario chiama Quicksort stesso con il sovraccarico dato dal calcolo del
Max.
Sub linearSort(v() As Long)
Dim lngMax As Long
Dim a As Long ' contatore
Dim b As Long ' contatore
Dim c As Long ' puntatore in scrittura
lngMax = v(LBound(v))
For a = LBound(v) + 1 To UBound(v)
    If v(a) > lngMax Then lngMax = v(a)
Next
If lngMax > 16777215 Then
    ' dovrei dimensionare un array di oltre 16777216 elementi long=128MB
    ' occuperei troppa memoria: chiamo un ordinamento tradizionale
    Call quickSort(v())
    Exit Sub
Else
    ReDim buf(0 To lngMax) As Long
    For a = LBound(v) To UBound(v)
        buf(v(a)) = buf(v(a)) + 1
    Next
    For a = LBound(buf) To UBound(buf)
        b = buf(a)
        While b <> 0
            v(c) = a
            c = c + 1
            b = b - 1
        Wend
    Next


 Ricordati i prerequisiti: array di long non negativi.
Passando a sortarrbin() la matrice x(n) di long, il valore di x(0) lo
modifica in 0. Ricordi di questo comportamento?
Ciao,SK

 Ricordati i prerequisiti: array di long non negativi.
Scusami, ho sbagliato, non modifica il primo elemento ma slitta quelli
passatigli in pasto di una posizione e aggiunge un elemento x(0) che ha
valore 0.
Ciao e ancora grazie, SK

 modifica in 0. Ricordi di questo comportamento?
No, ho provato diversi array generati casualmente senza problemi, però non
si sa mai; se il tuo array è piccolo puoi postarlo?
x:termoPilucco

 si sa mai; se il tuo array č piccolo puoi postarlo?
E' proprio cosě. aggiunge un elemento con indice 0 alla matrice che diventa
di 11 elementi.
Verficalo cosě:
Private Sub Command1_Click()
Randomize
Dim x(10) As Long
Dim i As Integer
For i = 0 To 9
x(i) = Int((30 - 1 + 1) * Rnd + 1)
Next
sortarrbin x() 'in modulo termopilucco.bas ;-)
For i = 0 To 9
Debug.Print x(i)
Next
End Sub
Ciao, SK

 si sa mai; se il tuo array č piccolo puoi postarlo?
Forse ho risolto. ho cambiato questa chiamata da cosě
Call sortbit(v(), lmx - 1, LBound(v), UBound(v) )
a cosě
Call sortbit(v(), lmx - 1, LBound(v), UBound(v) - 1).
Ciao, SK

 For i = 0 To 9
Quindi qui dovresti usare "0 to 10" o, meglio, lbound(x) to ubound(x).
Altrimenti l'ultimo elemento rimane (non essendo inizializzato) a zero,
quindi hai quel "comportamento".
In pratica se vuoi 10 elementi devi dimensionare l'array cosě:
Dim x(9) As Long
equivalente (se option base=0) a:
Dim x(o to 9) As Long
x:termoPilucco.