Jump to content

Gerando Combinações Sem Repetição


Leudassdf
 Share

Recommended Posts

Boas pessoal. eu estou a tentar gerar todas as combinações possíveis para 30 números sendo que preciso de gerar 5 para escrever numa string. tipo fazer combinações como no euromilhoes. Mas e fazer todas as combinações possíveis.

Não e saber o numero de combinações mas sim gerar todas as combinações possíveis sem repetição.

Será que alguém tem ideia de como posso fazer...?

Cumprimentos

Link to comment
Share on other sites

Boas jlpcalado. Estive a consultar o topico e nao percebi o bem aquilo que esse topico faz.

Volto a referir que eu quero todas as combinaçoes possiveis por exemplo para 30 numeros. nos quais escolho por ex 5.

Eu queria colocar todas as combinações num array pois e mais rapido de preencher os milhoes de combinaçoes possiveis.

O topico que me deste era algo parecido? e que nao consegui perceber....

Obrigada,

Abraço

Boas jlpcalado. Estive a consultar o topico e nao percebi o bem aquilo que esse topico faz.

Volto a referir que eu quero todas as combinaçoes possiveis por exemplo para 30 numeros. nos quais escolho por ex 5.

Eu queria colocar todas as combinações num array pois e mais rapido de preencher os milhoes de combinaçoes possiveis. Mas se for mais facil como o datagridview tambem nao ha problema. apenas se torna mais lento

O topico que me deste era algo parecido? e que nao consegui perceber....

Obrigada,

Abraço

Link to comment
Share on other sites

Talvez seja mais fácil modificar o exemplo.

Coloca no form1 um 'Button2' , uma textbox 'txtnumeros' e uma 'DataGridView1'

Na 'txtnumeros' insere uma string com os nºs que desejas separados por virgulas ( 1,2,6,12,13,17,..., 45)

Clica no button2

Public Class Form1
   Dim matrizNum
   Dim matrizSeq
   Dim table As DataTable
   Dim contador As Integer = 0
   Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    table = New DataTable
    table.Columns.Add("Id", GetType(Integer))
    table.Columns.Add("n1", GetType(Integer))
    table.Columns.Add("n2", GetType(Integer))
    table.Columns.Add("n3", GetType(Integer))
    table.Columns.Add("n4", GetType(Integer))
    table.Columns.Add("n5", GetType(Integer))
   End Sub
   Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)
    Dim seqTemp As String : Dim limiteElem As Integer
    limiteElem = totalNum - (totalElementos - ElementoAtual)
    For i = num To limiteElem
	    seqTemp = sequencia & (matrizNum(i - 1))
	    If ElementoAtual < totalElementos Then
		    Call geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & "  ")
	    Else
		    matrizSeq = Split(seqTemp, "  ")
		    contador += 1
		    table.Rows.Add(contador, matrizSeq(0), matrizSeq(1), matrizSeq(2), matrizSeq(3), matrizSeq(4))
	    End If
    Next i
   End Sub
   Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
    matrizNum = Split(txtnumeros.Text, ",")
    Call geraComb(UBound(matrizNum) + 1, 5, 1, 1, "")  ' combinações 5 a 5
    DataGridView1.DataSource = table
    ToolStripStatusLabel1.Text = table.Rows.Count.ToString
   End Sub
end class
Link to comment
Share on other sites

Eu tenho isto: (e praticamente tudo igual ao teu)


Public Class Form1
Dim matrizNum

Dim matrizSeq
Dim table As DataTable
Dim contador As Integer = 0
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
	Dim table As New DataTable
	table = New DataTable
	table.Columns.Add("Id", GetType(Integer))
	table.Columns.Add("n1", GetType(Integer))
	table.Columns.Add("n2", GetType(Integer))
	table.Columns.Add("n3", GetType(Integer))
	table.Columns.Add("n4", GetType(Integer))
	table.Columns.Add("n5", GetType(Integer))
End Sub

Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
	matrizNum = Split(txtnumeros.Text, ",")
	geraComb(UBound(matrizNum) + 1, 5, 1, 1, "")  ' combinações 5 a 5
	DataGridView1.DataSource = table
	'ToolStripStatusLabel1.Text = table.Rows.Count.ToString

End Sub

Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)

	Dim seqTemp As String : Dim limiteElem As Integer
	limiteElem = totalNum - (totalElementos - ElementoAtual)
	For i = num To limiteElem
		seqTemp = sequencia & (matrizNum(i - 1))
		If ElementoAtual < totalElementos Then
			geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & "  ")
		Else
			matrizSeq = Split(seqTemp, "  ")
			contador += 1
			table.Rows.Add(contador, matrizSeq(0), matrizSeq(1), matrizSeq(2), matrizSeq(3), matrizSeq(4))
		End If
	Next
End Sub
End Class

mas isto nao faz nada. se tentares executares nao obtens nada. e como se nao tivesses codigo. pelo menos para mim...

Link to comment
Share on other sites

Retira o "Dim table" do form1_Load

A variável 'table' passa a ser local qdo deve ser global

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
' Dim table As New DataTable
table = New DataTable

....

Funcionou perfeitamente. agora vou tentar adaptar. ou melhor ia mas o código esta "complicado" para mim.

Seria possível explicares-me algumas partes tipo:

matrizNum = Split(txtnumeros.Text, ",")   'isto faz o que?
 Call geraComb(UBound(matrizNum) + 1, 5, 1, 1, "") ' e esta? nao percebi mesmo. chamas a funçao geraComb certo? e depois para que serve o Ubound....

por ultimo isto e que foi mesmo zero

Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)
 Dim seqTemp As String : Dim limiteElem As Integer ' qual a razao dos : pontos?
 limiteElem = totalNum - (totalElementos - ElementoAtual) 'igualas a variavel a limiteElem mas o valor de totalnum, totalelementos e elemento actual foram defenidos? como e que sse sabe o valor desses..? ja agora porque e que ao criares a sub colocas o byval... as...? isto e tipo uma declaraçao de variavel?
 For i = num To limiteElem
   seqTemp = sequencia & (matrizNum(i - 1))
   If ElementoAtual < totalElementos Then 'o elemento actual e constante? nao pois nao? entao mas onde e que ele incrementa para saber qual e esse valor?
     geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & "  ")'  e isto?
   Else
     matrizSeq = Split(seqTemp, "  ") 'este tambem nao percebi
     contador += 1
     table.Rows.Add(contador, matrizSeq(0), matrizSeq(1), matrizSeq(2), matrizSeq(3), matrizSeq(4)) 'como e que aqui consegues inserir valores na tabela? isto sao arrays? se sao como e que os declaras-te? normalmente para declarar arrays faco tipo dim nomearray(50) as integer
   End If
 Next
End Sub

Sei que sao muitas perguntas mas se me pudesse ajudar a aumentar o meu conhecimento agradecia imenso. De qualquer das maneiras tenho qu agradecer desde ja por todo o auxilio que me prestou pois este era um dos projectos que queria ver resolvido a muito mas ainda nao tinha conseguido perceber como gerar todos os numeros diferentes.

Muito obrigada mesmo jlpcalado.

Cumprimentos 👍

Link to comment
Share on other sites

Bom. Isto não estava no programa, mas vamos lá a ver

matrizNum = Split(txtnumeros.Text, ",") 'isto faz o que? - dada a string "1,2,3,4,5,6,7" considera que os elementos são separados por virgula e cria um array

Call geraComb(UBound(matrizNum) + 1, 5, 1, 1, "") ' e esta? nao percebi mesmo. chamas a funçao geraComb certo? e depois para que serve o Ubound....

Ubound (de upper bound) retorna o nº do indice mais elevado do array

por ultimo isto e que foi mesmo zero

Esta função foi criada pelo Chamuanza e está muito bem gizada.

Como já reparaste, dentro dela chama-se a si própria - são chamadas funções RECURSIVAS.

Faz debug colocando um breakpoint no 'geracomb' interno e no 'table.Rows.Add' e faz watch das variáveis da função p/ veres a evoluçaõ da função.

Vais ver que é um pouco parecido com o percorrer os ramos de uma árvore.

Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)

Dim seqTemp As String : Dim limiteElem As Integer ' qual a razao dos : pontos? - serve só como separador de instruções (em vez de escrevesres noutra linha

limiteElem = totalNum - (totalElementos - ElementoAtual)igualas a variavel a limiteElem mas o valor de totalnum, totalelementos e elemento actual foram defenidos? como e que sse sabe o valor desses..? ja agora porque e que ao criares a sub colocas o byval... as...? isto e tipo uma declaraçao de variavel?

- há 2 maneiras de passar variaveis: 'byVal' ou 'byRef'. A principal diferença é que se passares uma variável por referência (byRef) o seu valor pode ser alterado dentro da função e 'byVal' não.

For i = num To limiteElem

seqTemp = sequencia & (matrizNum(i - 1))

If ElementoAtual < totalElementos Then 'o elemento actual e constante? nao pois nao? entao mas onde e que ele incrementa para saber qual e esse valor? - faz o debug que te disse acima e vais ver que vai mudando

geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & " ")' 😕 e isto? - Chamada interna à função - salta de novo para o início da função

Else

matrizSeq = Split(seqTemp, " " este tambem nao percebi - o mesmo que o split acima só que o separador é ' ' (espaço)

contador += 1

table.Rows.Add(contador, matrizSeq(0), matrizSeq(1), matrizSeq(2), matrizSeq(3), matrizSeq(4))como e que aqui consegues inserir valores na tabela? isto sao arrays? se sao como e que os declaras-te? normalmente para declarar arrays faco tipo dim nomearray(50) as integer

- matrizSeq é um array e podia ter sido definido como Dim MatrizSeq(4) as string sem problemas

- matrizSeq(i) representa o valor contido no indice i do array

End If

Next

End Sub

Link to comment
Share on other sites

Bom. Isto não estava no programa, mas vamos lá a ver

matrizNum = Split(txtnumeros.Text, ",") 'isto faz o que? - dada a string "1,2,3,4,5,6,7" considera que os elementos são separados por virgula e cria um array

Call geraComb(UBound(matrizNum) + 1, 5, 1, 1, "") ' e esta? nao percebi mesmo. chamas a funçao geraComb certo? e depois para que serve o Ubound....

Ubound (de upper bound) retorna o nº do indice mais elevado do array

por ultimo isto e que foi mesmo zero

Esta função foi criada pelo Chamuanza e está muito bem gizada.

Como já reparaste, dentro dela chama-se a si própria - são chamadas funções RECURSIVAS.

Faz debug colocando um breakpoint no 'geracomb' interno e no 'table.Rows.Add' e faz watch das variáveis da função p/ veres a evoluçaõ da função.

Vais ver que é um pouco parecido com o percorrer os ramos de uma árvore.

Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)

Dim seqTemp As String : Dim limiteElem As Integer ' qual a razao dos : pontos? - serve só como separador de instruções (em vez de escrevesres noutra linha

limiteElem = totalNum - (totalElementos - ElementoAtual)igualas a variavel a limiteElem mas o valor de totalnum, totalelementos e elemento actual foram defenidos? como e que sse sabe o valor desses..? ja agora porque e que ao criares a sub colocas o byval... as...? isto e tipo uma declaraçao de variavel?

- há 2 maneiras de passar variaveis: 'byVal' ou 'byRef'. A principal diferença é que se passares uma variável por referência (byRef) o seu valor pode ser alterado dentro da função e 'byVal' não.

For i = num To limiteElem

seqTemp = sequencia & (matrizNum(i - 1))

If ElementoAtual < totalElementos Then 'o elemento actual e constante? nao pois nao? entao mas onde e que ele incrementa para saber qual e esse valor? - faz o debug que te disse acima e vais ver que vai mudando

geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & " ")' 😕 e isto? - Chamada interna à função - salta de novo para o início da função

Else

matrizSeq = Split(seqTemp, " " este tambem nao percebi - o mesmo que o split acima só que o separador é ' ' (espaço)

contador += 1

table.Rows.Add(contador, matrizSeq(0), matrizSeq(1), matrizSeq(2), matrizSeq(3), matrizSeq(4))como e que aqui consegues inserir valores na tabela? isto sao arrays? se sao como e que os declaras-te? normalmente para declarar arrays faco tipo dim nomearray(50) as integer

- matrizSeq é um array e podia ter sido definido como Dim MatrizSeq(4) as string sem problemas

- matrizSeq(i) representa o valor contido no indice i do array

End If

Next

End Sub

Boas jlpcalado

Muito obrigada pela excelente explicaçao. fiquei ainda com algumas duvidas em relaçao a declaraçao do sub:

Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)

Fiz os breakpoint em diversas situaçao e neste if: If ElementoAtual < totalElementos Then reparei que muitas das vezes o elemento actual e o totalelementos e 5. mas nao consegui perceber de onde e que vem aquele 5.E que fazes o byval que pelo que percebi e um valor fixo mas onde e que existe o declaraçao do valor das variaveis totalElementos e ElementoAtual?

Muito obrigada pela explicaçao.

Cumrimentos

Link to comment
Share on other sites

Boas Jlpcalado.

Eu estive a avaliar o codigo e ouve situaçoes complexas as quais nao consegui descobrir a logica. Principalmente nao percebi como sao gerados os numeros sem repetiçao. gostava de saber se tens algum algoritmo que possa ser-me util para eu entender isto. porque eu tenho que completar esta situaçao com mais uns valores e so se consegui entender a logica de como os numeros sao gerados e que irei consegui.

Se me pudesses ajudar novamente agradecia.

Cumprimentos

Link to comment
Share on other sites

Olá Leudassdf.

Espero que o código comentado que envio esclareça as tuas dúvidas - tenta refazer esta versão que permite diferentes combinações não só de números.

Um abraço

Public Class Form1
   Dim matrizNum : Dim matrizSeq : Dim table As DataTable : Dim contador As Integer
   Private Sub btGerar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btGerar.Click
       'criar dinâmica/ tabela que vai receber as combinações
       table = New DataTable
       table.Columns.Add("Id", GetType(Integer)) ' 1ª coluna autonumber = contador
       'Criar o número de colunas em função do nº de combinações n a n pretendidas, n=txtelementos.Text
       For i = 1 To CInt(txtelementos.Text)
           table.Columns.Add("n" & i.ToString)
       Next
       table.Clear()  ' limpar todos os registos da tabela
       contador = 0    ' iniciar contador
       ' criar uma matriz com os números (tb pode ser strings) da txtnumeros que devem ser separados por ','
       matrizNum = Split(txtnumeros.Text, ",")
       'iniciar a geração de combinações - passa o nº total de elementos da matriz,o nº de colunas (p/ além da 1ª),
       'o ElementoAtual e num =1 e a sequencia inicial vazia
       geraComb(UBound(matrizNum) + 1, CInt(txtelementos.Text), 1, 1, "")
       DataGridView1.DataSource = table
   End Sub
   Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)
       Dim seqTemp As String : Dim limiteElem As Integer : Dim dr As DataRow
       'O segredo das funções recursivas é que elas se chamam a si próprias não esquecendo o sitio em que se encontravam
       'para "1,2,3,4,5,6" 3 a 3 a sequência de chaamadas à função é:
       ' 1, 12, 123, 124, 125, 126 - volta 12 e passa a 13, 134, ... 14,... 15, 156 e volta para 1 e passa 2 ....
       ' como já tinha dito é parecido com o percorrer os ramos de uma árvore.
       'Tome-se por exemplo txtelementos.text=3
       'ElementoAtual representa o nº de elementos na sequencia
       'Só quando limiteElem = totalNum irá ser adicionada uma combinação à tabela, noutra perspetiva:
       'só quando o numero de elementos da sequencia for igual 3
       limiteElem = totalNum - (totalElementos - ElementoAtual)
       For i = num To limiteElem  ' num representa a posição do elemento na matrizNum
           seqTemp = sequencia & (matrizNum(i - 1)) ' recria a sequencia acrescentando o valor da posição i-1 da matrizNum
           If ElementoAtual < totalElementos Then
               ' se o nº de elementos na seqTemp for < 3, incrementa ElementoAtual e o 'num'
               geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & "  ")
           Else
               matrizSeq = Split(seqTemp, "  ") ' cria uma matriz a partir da seqTemp retirando os espaços
               contador += 1
               Try
                   'adiciona a nova combinação
                   dr = table.NewRow
                   dr(0) = contador
                   For k = 1 To table.Columns.Count - 1
                       dr(k) = matrizSeq(k - 1)
                   Next
                   table.Rows.Add(dr)
               Catch ex As Exception
                   MsgBox(ex.Message)
               End Try
           End If
       Next
   End Sub
End Class
  • Vote 1
Link to comment
Share on other sites

Olá Leudassdf.

Espero que o código comentado que envio esclareça as tuas dúvidas - tenta refazer esta versão que permite diferentes combinações não só de números.

Um abraço

Public Class Form1
Dim matrizNum : Dim matrizSeq : Dim table As DataTable : Dim contador As Integer
Private Sub btGerar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btGerar.Click
	'criar dinâmica/ tabela que vai receber as combinações
	table = New DataTable
	table.Columns.Add("Id", GetType(Integer)) ' 1ª coluna autonumber = contador
	'Criar o número de colunas em função do nº de combinações n a n pretendidas, n=txtelementos.Text
	For i = 1 To CInt(txtelementos.Text)
		table.Columns.Add("n" & i.ToString)
	Next
	table.Clear()  ' limpar todos os registos da tabela
	contador = 0	' iniciar contador
	' criar uma matriz com os números (tb pode ser strings) da txtnumeros que devem ser separados por ','
	matrizNum = Split(txtnumeros.Text, ",")
	'iniciar a geração de combinações - passa o nº total de elementos da matriz,o nº de colunas (p/ além da 1ª),
	'o ElementoAtual e num =1 e a sequencia inicial vazia
	geraComb(UBound(matrizNum) + 1, CInt(txtelementos.Text), 1, 1, "")
	DataGridView1.DataSource = table
End Sub
Sub geraComb(ByVal totalNum As Integer, ByVal totalElementos As Integer, ByVal ElementoAtual As Integer, ByVal num As Integer, ByVal sequencia As String)
	Dim seqTemp As String : Dim limiteElem As Integer : Dim dr As DataRow
	'O segredo das funções recursivas é que elas se chamam a si próprias não esquecendo o sitio em que se encontravam
	'para "1,2,3,4,5,6" 3 a 3 a sequência de chaamadas à função é:
	' 1, 12, 123, 124, 125, 126 - volta 12 e passa a 13, 134, ... 14,... 15, 156 e volta para 1 e passa 2 ....
	' como já tinha dito é parecido com o percorrer os ramos de uma árvore.
	'Tome-se por exemplo txtelementos.text=3
	'ElementoAtual representa o nº de elementos na sequencia
	'Só quando limiteElem = totalNum irá ser adicionada uma combinação à tabela, noutra perspetiva:
	'só quando o numero de elementos da sequencia for igual 3
	limiteElem = totalNum - (totalElementos - ElementoAtual)
	For i = num To limiteElem  ' num representa a posição do elemento na matrizNum
		seqTemp = sequencia & (matrizNum(i - 1)) ' recria a sequencia acrescentando o valor da posição i-1 da matrizNum
		If ElementoAtual < totalElementos Then
			' se o nº de elementos na seqTemp for < 3, incrementa ElementoAtual e o 'num'
			geraComb(totalNum, totalElementos, ElementoAtual + 1, i + 1, seqTemp & "  ")
		Else
			matrizSeq = Split(seqTemp, "  ") ' cria uma matriz a partir da seqTemp retirando os espaços
			contador += 1
			Try
				'adiciona a nova combinação
				dr = table.NewRow
				dr(0) = contador
				For k = 1 To table.Columns.Count - 1
					dr(k) = matrizSeq(k - 1)
				Next
				table.Rows.Add(dr)
			Catch ex As Exception
				MsgBox(ex.Message)
			End Try
		End If
	Next
End Sub
End Class

Caro jlpcalado muito obrigada pela explicaçao.

Estou so a tentar perceber isto.

Ao recriar a seqtemp o que e que ela faz mesmo? incialmente como a sequencia e "" nao adiciona nada a nao ser o 1 valor do array(0). mas como e que depois ele faz o incremento no 4 numero? ou seja inicialmente começa por 1-2-3-4-5 ate 1-2-3-4-50, depois como e que ele muda para 1-2-3--5-6?

Link to comment
Share on other sites

Outra forma de ver as funções recursivas é o de que funcionam como caixas dentro de caixas em que cada caixa pode conter 1 ou várias.

Imagina que na 1ª vez que chamas a função estás a dizer abre a caixa1

O que acontece de seguida é que ao abri-la (e antes de fechar) ela diz abre a caixa12, que por sua vez diz abre a caixa 123

Como esta caixa "tem premio" retira-o e passa o controlo à caixa12 que pergunta: A caixa 123 é a última que eu tenho? Resp: Não - passa à Caixa124

... isto continua até à ultima caixa (caixa12[50]) da caixa12

Depois de tirar o prémio da última caixa o controlo é passado de novo à caixa12 que faz a pergunta de novo.

Como não tem mais caixas passa o controlo `caixa1 - que verifica que também tem a caixa13 e recomeça o processo ...

A chamada à caixa2 só será iniciada quando tiver passado por todas as caixas da caixa1

Percebes agora mais um pouco?

Uma função recursiva histórica á a função fatorial (n!) :

Private Function Factorial(ByVal numero As integer) As integer

If numero <= 1 Then

Return 1

Else

Return numero * Fatorial(numero - 1)

End If

End Function

Por exemplo: Calcule o 10!

Na 1ª vez a f. diz qie 10!=10x9!

Na 2ª 9!=9x8!

...

Repara que a 1ª vez só fica completada depois de serem completadas todas as internas. OK?

Podes encontrar um exemplo interessante(?!) e eventual/ útil em

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=1604&lngWId=10

Link to comment
Share on other sites

Outra forma de ver as funções recursivas é o de que funcionam como caixas dentro de caixas em que cada caixa pode conter 1 ou várias.

Imagina que na 1ª vez que chamas a função estás a dizer abre a caixa1

O que acontece de seguida é que ao abri-la (e antes de fechar) ela diz abre a caixa12, que por sua vez diz abre a caixa 123

Como esta caixa "tem premio" retira-o e passa o controlo à caixa12 que pergunta: A caixa 123 é a última que eu tenho? Resp: Não - passa à Caixa124

... isto continua até à ultima caixa (caixa12[50]) da caixa12

Depois de tirar o prémio da última caixa o controlo é passado de novo à caixa12 que faz a pergunta de novo.

Como não tem mais caixas passa o controlo `caixa1 - que verifica que também tem a caixa13 e recomeça o processo ...

A chamada à caixa2 só será iniciada quando tiver passado por todas as caixas da caixa1

Percebes agora mais um pouco?

Uma função recursiva histórica á a função fatorial (n!) :

Private Function Factorial(ByVal numero As integer) As integer

If numero <= 1 Then

Return 1

Else

Return numero * Fatorial(numero - 1)

End If

End Function

Por exemplo: Calcule o 10!

Na 1ª vez a f. diz qie 10!=10x9!

Na 2ª 9!=9x8!

...

Repara que a 1ª vez só fica completada depois de serem completadas todas as internas. OK?

Podes encontrar um exemplo interessante(?!) e eventual/ útil em

http://www.planet-source-code.com/vb/scripts/ShowCode.asp?txtCodeId=1604&lngWId=10

Caro jlpcalado

Ao fazeres geraComb(UBound(matrizNum) + 1, CInt(txtelementos.Text), 1, 1, "") estas a declarar os valores para o num etc certo?

no ciclo for no meu caso existem 50 numeros, logo quando ele chega ao numero 50 o programa altera o valor do elemento actual passa para 4.

No entanto em condiçoes normais (para mim) teria que fazer algo do genero elementoactual=elementoactual-1. No entanto aqui e diferente. mas como e que ele faz isso? e como e que o programa no final do for volta a repetir-se? ou melhor como e que se volta a chamar a funçao?

Link to comment
Share on other sites

Está um pouco difícil !!...

Iniciemos:

1 - A f é chamada com os valores (50,5,1,1,'') ' (-consideremos chamada = c1)

2 - dentro da c1 faz seqTemp="1" e por força das condições

3 - faz c2 onde seqTemp="1 2" e por força das condições

4 - faz c3 - seqTemp="1 2 3" e ... c4 - seqTemp="1 2 3 4" .....e c5 - seqTemp="1 2 3 4 5"

5 - como em c5 a combinação serve, adiciona a combinação e termina a chamada c5

6 - qual a chamada que recebe o controlo - a c4 que ficou em 'stand by' e que tinha chamado a c5

7 - a c4 incrementa o ElementoAtual com que foi chamada (era 4 passa a 5) e o num (do For i = num To limiteElem - o i era 5 passa a 6)

8 - chama c6(50,5,5,6)

9 - c6 recolhe cobinação e passa de no a c4

10 - c4 incrementa o ElementoAtual (era 4 passa a 5) e o num (i+1 - era 6 passa a 7)

-----

11 - a c4 só termina qdo seqTemp="1 2 3 4 50" e no regresso já não puder fazer i+1 porque i=limiteElem

12 - como c4 só tem 4 elementos acaba e passa o controlo a c3 que faz seqTemp="1 2 4" ...por força das condições

... depois de muitas voltas, c3 há-de passar a c2 que faz seqTemp="1 3"

....

33..56(!!...) c2 passa a c1 que faz seqTemp="2"

Estás a perceber agora?

As chamadas são encadeadas e só terminam depois de todas as que lhe são internas terminarem.

Link to comment
Share on other sites

Realmente estava dificil, ma

Está um pouco difícil !!...

Iniciemos:

1 - A f é chamada com os valores (50,5,1,1,'') ' (-consideremos chamada = c1)

2 - dentro da c1 faz seqTemp="1" e por força das condições

3 - faz c2 onde seqTemp="1 2" e por força das condições

4 - faz c3 - seqTemp="1 2 3" e ... c4 - seqTemp="1 2 3 4" .....e c5 - seqTemp="1 2 3 4 5"

5 - como em c5 a combinação serve, adiciona a combinação e termina a chamada c5

6 - qual a chamada que recebe o controlo - a c4 que ficou em 'stand by' e que tinha chamado a c5

7 - a c4 incrementa o ElementoAtual com que foi chamada (era 4 passa a 5) e o num (do For i = num To limiteElem - o i era 5 passa a 6)

8 - chama c6(50,5,5,6)

9 - c6 recolhe cobinação e passa de no a c4

10 - c4 incrementa o ElementoAtual (era 4 passa a 5) e o num (i+1 - era 6 passa a 7)

-----

11 - a c4 só termina qdo seqTemp="1 2 3 4 50" e no regresso já não puder fazer i+1 porque i=limiteElem

12 - como c4 só tem 4 elementos acaba e passa o controlo a c3 que faz seqTemp="1 2 4" ...por força das condições

... depois de muitas voltas, c3 há-de passar a c2 que faz seqTemp="1 3"

....

33..56(!!...) c2 passa a c1 que faz seqTemp="2"

Estás a perceber agora?

As chamadas são encadeadas e só terminam depois de todas as que lhe são internas terminarem.

realmente estava dificil mas agora ja esta tudo mais claro...

Muito obrigada

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

By using this site you accept our Terms of Use and Privacy Policy. We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.