|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
[Visual Basic] - Combinazioni con ripetizione
Salve ragazzi,
vorrei realizzare una programma scritto in Visual Basic che mi elabora tutte le combinazioni possibili di N numeri a gruppi di K. Ad esempio se ho queste 4 lettere: a,b,c,d il mio programma deve essere in grado di elaborare tutte le seguenti possibili 20 combinazioni non ordinate: a b c-a b d-a c d-b c d a a a-b b a-c c a-d d a a a b-b b b-c c b-d d b a a c-b b c-c c c-d d c a a d-b b c-c c d-d d d Mi aiutate? Grazie
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Combinazioni con ripetizione su N elementi di classe K.
Io l'ho risolto così : Codice:
Public Function CombinazioniConRipetizione(ByVal arrayElementi() As String, ByVal classe As Byte) As List(Of String)
Dim LC As New List(Of String)
If arrayElementi.Count = 0 Then Return LC
If classe = 0 Then Return LC
Dim aP(classe - 1) As Integer
Dim C As String = ""
Do
C = ""
For i As Integer = 0 To aP.Count - 1
C = C & arrayElementi(aP(i))
Next
LC.Add(C)
Dim cnt As Integer = 0
For i As Integer = aP.Count - 1 To 0 Step -1
If aP(i) = arrayElementi.Count - 1 Then
cnt += 1
If cnt = aP.Count Then Exit Do
Else
aP(i) += 1
For j = 0 To aP.Count - 1
If i < j Then aP(j) = aP(i)
Next
Exit For
End If
Next
Loop
Return LC
End Function
|
|
|
|
|
|
#3 | |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
Quote:
Ciao e grazie 1000 per il codice Quando lo inserisco in Visual Basic mi da degli errori, indicati in rosso, come indicato nella figura. Non riesco a capire se ilcodice contiene delle parti da te commentate: ![]() Probabilmente l'errore è dovuto al fatto che sto utilizzando VBA e non VB... Ti dispiacerebbe mandarmi il file vbp completo?
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Il mio è codice VB 2008, quindi .NET. Devi fare le opportune modifiche, prima fra tutte la sostituzione della List() con un array ( utilizzando ReDim Preserve sullo stesso ad ogni inserimento di una nuova combinazione C ). Inoltre le dichiarazioni sulla stessa linea vanno "spezzate", perchè VBA non le supporta...
Se ho tempo più tardi vedo di postare anche una soluzione VBA, intanto vedi se ce la fai a tradurre... |
|
|
|
|
|
#5 | |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
Quote:
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
|
#6 | |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
Quote:
Codice:
Sub CombinazioniConRipetizione(n As Long, k As Long)
Dim aP() As Long
Dim C As String
Dim cnt As Long
Dim arrayElementi() As Long
ReDim aP(k) As Long
ReDim arrayElementi(n) As Long
lstCombinazioni.Clear
Do
C = ""
For i = 0 To UBound(aP) - 1
C = C & CStr(aP(i))
Next
lstCombinazioni.AddItem C
cnt = 0
For i = UBound(aP) - 1 To 0 Step -1
If aP(i) = UBound(arrayElementi) - 1 Then
cnt = cnt + 1
If cnt = UBound(aP) Then Exit Do
Else
aP(i) = aP(i) + 1
For j = 0 To UBound(aP) - 1
If i < j Then aP(j) = aP(i)
Next
Exit For
End If
Next
Loop
lblContatore = lstCombinazioni.ListCount
End Sub
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
Ultima modifica di lucausa75 : 12-11-2009 alle 15:47. |
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Ok. Posto anche la mia versione VBA della CombinazioniConRipetizione, sotto forma di Function, valida per ogni utilizzo. Il tipo restituito è una Collection, che è abbastanza "simile" ( parola grossa ) alla List() di VB.NET... :
Codice:
Public Function CombinazioniConRipetizione(arrayElementi() As Variant, classe As Byte) As Collection
Dim LC As New Collection
If UBound(arrayElementi) = 0 Then
Set CombinazioniConRipetizione = LC
End If
If classe = 0 Then
Set CombinazioniConRipetizione = LC
End If
Dim aP() As Integer
ReDim aP(classe - 1)
Dim i As Integer
Dim j As Integer
Dim C As String
Dim cnt As Integer
Do
C = ""
For i = 0 To UBound(aP)
C = C & arrayElementi(aP(i))
Next i
LC.Add (C)
cnt = 0
For i = UBound(aP) To 0 Step -1
If aP(i) = UBound(arrayElementi) Then
cnt = cnt + 1
If cnt = UBound(aP) + 1 Then Exit Do
Else
aP(i) = aP(i) + 1
For j = 0 To UBound(aP)
If i < j Then aP(j) = aP(i)
Next
Exit For
End If
Next i
Loop
Set CombinazioniConRipetizione = LC
End Function
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
Quote:
Ottimo Ma se volessimo parlare di Combinazioni SENZA Ripetizione ? Avete una Function o una Sub già pronta? Grazie 1000!
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Basta aggiustare qualcosa : - Mentre nelle combinazioni con ripetizione la classe può anche superare il numero di elementi dell'insieme N, nelle combinazioni semplici no. - L'array delle posizioni aP() va inizializzato alla prima posizione valida ( non devono essere tutti zero ). - Quando nel ciclo For interno un elemento di aP() viene incrementato di 1, quelli di indice maggiore vanno aggiornati diversamente. Per il resto è molto simile alla precedente ( sempre per VB 2008 - a te il piacere di tradurre... Codice:
Public Function CombinazioniSemplici(ByVal arrayElementi() As String, ByVal dimensioneGruppo As Byte) As List(Of String)
Dim LC As New List(Of String)
If arrayElementi.Count = 0 Then Return LC
If dimensioneGruppo = 0 Or dimensioneGruppo > arrayElementi.Count Then Return LC
Dim aP(dimensioneGruppo - 1) As Integer
For i As Integer = 0 To aP.Count - 1
aP(i) = i
Next
Dim C As String = ""
Do
C = ""
For i As Integer = 0 To aP.Count - 1
C = C & arrayElementi(aP(i))
Next
LC.Add(C)
Dim cnt As Integer = 0
For i As Integer = aP.Count - 1 To 0 Step -1
If aP(i) = arrayElementi.Count - 1 - cnt Then
cnt += 1
If cnt = aP.Count Then Exit Do
Else
aP(i) += 1
For j = 0 To aP.Count - 1
If i < j Then aP(j) = aP(i) + (j - i)
Next
Exit For
End If
Next
Loop
Return LC
End Function
|
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
Quote:
Grazie 1000 per il codice che ho tradotto correggendoti, probabilmente, un errore in entrambe le funzioni: Codice:
NO
For i As Integer = 0 To aP.Count - 1
C = C & arrayElementi(aP(i))
Next
SI
For i As Integer = 0 To aP.Count - 1
C = C & aP(i)
Next
Cmq così come ho tradotto le due routine funziona: Codice:
Sub CombinazioniConRipetizione(n As Long, k As Long)
Dim i As Long
Dim j As Long
Dim aP() As Long
Dim C As String
Dim cnt As Long
Dim arrayElementi() As Long
ReDim aP(k) As Long
ReDim arrayElementi(n) As Long
lstCombinazioni.Clear
Do
C = ""
For i = 0 To UBound(aP) - 1
C = C & CStr(aP(i))
Next
lstCombinazioni.AddItem C
cnt = 0
For i = UBound(aP) - 1 To 0 Step -1
If aP(i) = UBound(arrayElementi) - 1 Then
cnt = cnt + 1
If cnt = UBound(aP) Then Exit Do
Else
aP(i) = aP(i) + 1
For j = 0 To UBound(aP) - 1
If i < j Then aP(j) = aP(i)
Next
Exit For
End If
Next
Loop
lblContatore = lstCombinazioni.ListCount
End Sub
Sub CombinazioniOrdinate(n As Long, k As Long)
Dim i As Long
Dim j As Long
Dim aP() As Long
Dim C As String
Dim cnt As Long
Dim arrayElementi() As Long
ReDim aP(k) As Long
ReDim arrayElementi(n) As Long
lstCombinazioni.Clear
For i = 0 To UBound(aP) - 1
aP(i) = i
Next
C = ""
Do
C = ""
For i = 0 To UBound(aP) - 1
C = C & CStr(aP(i))
Next
lstCombinazioni.AddItem C
cnt = 0
For i = UBound(aP) - 1 To 0 Step -1
If aP(i) = UBound(arrayElementi) - 1 - cnt Then
cnt = cnt + 1
If cnt = UBound(aP) Then Exit Do
Else
aP(i) = aP(i) + 1
For j = 0 To UBound(aP) - 1
If i < j Then aP(j) = aP(i) + (j - i)
Next
Exit For
End If
Next
Loop
lblContatore = lstCombinazioni.ListCount
End Sub
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
|
#11 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Non c'è alcun errore nelle mie Function. Appena ho un po' di tempo posto una soluzione completa di esempi di utilizzo...
|
|
|
|
|
|
#12 | |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
Quote:
...non mi permetterei mai di affermare che c'è un errore nelle tue funzioni è solo che trovo strano che apportando le correzioni da me suggerite mi funziona...cmq! Hai dato un'occhiata al mio codice in Visual Basic 6? Prova a far girare il codice prendendo come esempio questa pagina: http://www.ripmat.it/mate/l/lb/lbcb.html Grazie ancora!
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
|
#13 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
- Solitamente una Sub è meno generica e meno riutilizzabile di una Function, perciò non ho testato le tue Sub. Immagino che tu le abbia modificate per un motivo valido nel tuo caso. Nel mio caso ( con le Function ) l'array aP() è l'array delle posizioni, e NON va confuso con arrayElementi, che invece va passato in input alle Function e contiene gli N elementi dell'insieme. Perciò, nel mio caso : Codice:
C = C & arrayElementi(aP(i)) mentre : Codice:
C = C & aP(i) - Rimanendo in VBA, la Function corretta per le Combinazioni Semplici è la seguente : Codice:
Public Function CombinazioniSemplici(arrayElementi() As Variant, dimensioneGruppo As Byte) As Collection
Dim LC As New Collection
If UBound(arrayElementi) = 0 Then
Set CombinazioniSemplici = LC
End If
If dimensioneGruppo = 0 Or dimensioneGruppo > UBound(arrayElementi) Then
Set CombinazioniSemplici = LC
End If
Dim aP() As Integer
ReDim aP(dimensioneGruppo - 1)
Dim i As Integer
For i = 0 To UBound(aP)
aP(i) = i
Next i
Dim j As Integer
Dim C As String
Dim cnt As Integer
Do
C = ""
For i = 0 To UBound(aP)
C = C & arrayElementi(aP(i))
Next i
LC.Add (C)
cnt = 0
For i = UBound(aP) To 0 Step -1
If aP(i) = UBound(arrayElementi) - cnt Then
cnt = cnt + 1
If cnt = UBound(aP) + 1 Then Exit Do
Else
aP(i) = aP(i) + 1
For j = 0 To UBound(aP)
If i < j Then aP(j) = aP(i) + (j - i)
Next
Exit For
End If
Next i
Loop
Set CombinazioniSemplici = LC
End Function
Codice:
ListBox1.Clear
Dim N() As Variant
N = Array("a", "b", "c", "d")
Dim K As Byte
K = 3
Dim Comb As Collection
Set Comb = CombinazioniSemplici(N, K)
Dim i As Integer
For i = 1 To Comb.Count
ListBox1.AddItem (Comb(i))
Next i
MsgBox Comb.Count
Codice:
Public Function CombinazioniConRipetizione(arrayElementi() As Variant, classe As Byte) As Collection
Dim LC As New Collection
If UBound(arrayElementi) = 0 Then
Set CombinazioniConRipetizione = LC
End If
If classe = 0 Then
Set CombinazioniConRipetizione = LC
End If
Dim aP() As Integer
ReDim aP(classe - 1)
Dim i As Integer
Dim j As Integer
Dim C As String
Dim cnt As Integer
Do
C = ""
For i = 0 To UBound(aP)
C = C & arrayElementi(aP(i))
Next i
LC.Add (C)
cnt = 0
For i = UBound(aP) To 0 Step -1
If aP(i) = UBound(arrayElementi) Then
cnt = cnt + 1
If cnt = UBound(aP) + 1 Then Exit Do
Else
aP(i) = aP(i) + 1
For j = 0 To UBound(aP)
If i < j Then aP(j) = aP(i)
Next
Exit For
End If
Next i
Loop
Set CombinazioniConRipetizione = LC
End Function
Codice:
ListBox1.Clear
Dim N() As Variant
N = Array("a", "b", "c", "d")
Dim K As Byte
K = 3
Dim Comb As Collection
Set Comb = CombinazioniConRipetizione(N, K)
Dim i As Integer
For i = 1 To Comb.Count
ListBox1.AddItem (Comb(i))
Next i
MsgBox Comb.Count
Posso darle in pasto elementi di ogni tipo, come caratteri, stringhe, interi, decimali, currency e quant'altro : Codice:
Dim N() As Variant
N = Array("a", "b", "c", "d")
N = Array("str1", "str2", "str3", "str4")
N = Array(1, 2, 3, 4)
N = Array(1.11, 2.22, 3.33, 4.44)
...
...
Credo sia tutto molto più chiaro adesso. |
|
|
|
|
|
|
#14 |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
MarcoGG non ho parole: sei stato grande...anzi grandissimo
MarcoGG santo subito!!!
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
#15 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
|
|
|
|
|
|
#16 |
|
Senior Member
Iscritto dal: Jun 2001
Città: Catania
Messaggi: 2690
|
....e se adesso volessi realizzare un programma che mi visualizzi tutte le 24 (4!) disposizioni che si possono ottenere con le lettere: a, b, c, d?
Grazie
__________________
Unisciti a noi: http://www.swproduction.altervista.org/ - http://www.enews.altervista.org/
|
|
|
|
|
|
#17 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
E poi ci sono le Disposizioni di K su N, con K<N con e senza ripetizione, le Permutazioni, le Dismutazioni...
Beh, forza e coraggio ! Credo di aver già fonito parecchi spunti per continuare... |
|
|
|
|
|
#18 |
|
Junior Member
Iscritto dal: Jan 2010
Messaggi: 4
|
salve a tutti!!!
ho lettto tutto ,,, ee mi è venuto in mente unaa cosa..,,, se io volessi calcolare combinazioni ... in seguente modo ,,, a b c d e f g voglio che "a" si ripete solo in posizione 3 , 5, 7 "b" in pos2, pos4, pos6 "c" pos1, pos2, pos3, pos4, pos5, pos6, pos7 è possibile fare una cosa del genere ???? ehemm ........ scusate per italiano nn corretto |
|
|
|
|
|
#19 |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Non sono sicuro di aver capito cosa intendi, ma prova usando i miei codici, condizionando l'array delle posizioni in modo da tenere solo le posizioni desiderate...
|
|
|
|
|
|
#20 |
|
Junior Member
Iscritto dal: Jan 2010
Messaggi: 4
|
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:07.





















