Gerar números - um pouco confuso!
Bom dia a todos,
alguém teria disponível algum componente ou função para gerar números com uma ordem pré-estabelecida e armazená-los. Explicando melhor:
Vamos supor que os números dados sejam 1, 2 3, e 4. Ele faria a combinação desses números em terno, sem repetir nenhum valor, veja:
1 2 3
1 2 4
1 3 4
2 3 4
Depois jogaria num memo.
Alguém me dá uma luz?
Valeu!
alguém teria disponível algum componente ou função para gerar números com uma ordem pré-estabelecida e armazená-los. Explicando melhor:
Vamos supor que os números dados sejam 1, 2 3, e 4. Ele faria a combinação desses números em terno, sem repetir nenhum valor, veja:
1 2 3
1 2 4
1 3 4
2 3 4
Depois jogaria num memo.
Alguém me dá uma luz?
Valeu!
Anarchybra
Curtidas 0
Respostas
Marconi
10/11/2003
O que voce pode fazer é simples:
Coloque em uma Matriz os números que deseja
var M:Array of Array of word;
i,j,k:word;
begin
setlenght(M,4) // uzando o seu exemplo
M[0]:=1;
M[1]:=2;
M[2]:=3;
m[3]:=4;
// lembrando que uma matriz de 4 elementos vai de 0 a 3.
// agora é só montar o loop
for i:=0 to 1 do begin
for j:= i+1 to 2 do begin
for k:=j+1 to 3 do begin
memo1.lines.add(IntToStr(M[i])+´ ´+IntToStr(M[j])+IntToStr(M[k]));
end;
end;
end;
M.release; // limpando M da memória
end;
Espero ter ajudado
Marconi
Coloque em uma Matriz os números que deseja
var M:Array of Array of word;
i,j,k:word;
begin
setlenght(M,4) // uzando o seu exemplo
M[0]:=1;
M[1]:=2;
M[2]:=3;
m[3]:=4;
// lembrando que uma matriz de 4 elementos vai de 0 a 3.
// agora é só montar o loop
for i:=0 to 1 do begin
for j:= i+1 to 2 do begin
for k:=j+1 to 3 do begin
memo1.lines.add(IntToStr(M[i])+´ ´+IntToStr(M[j])+IntToStr(M[k]));
end;
end;
end;
M.release; // limpando M da memória
end;
Espero ter ajudado
Marconi
GOSTEI 0
Anarchybra
10/11/2003
Muito obrigado Marconi pela resposta marconi,
mas estou tendo problemas com o seu código.
Quando atribuo um valor a matriz ´M[0]:=1;´ e na conversão dentro do memo, ´IntToStr´.
Valeu!
mas estou tendo problemas com o seu código.
Quando atribuo um valor a matriz ´M[0]:=1;´ e na conversão dentro do memo, ´IntToStr´.
Valeu!
GOSTEI 0
Anarchybra
10/11/2003
Já resolvi o problema Marconi, mas estou com uma outra dúvida?
Onde determino a quantidade de Números e a quantidade de combinações, por exemplo:
Parace óbvio mas não consegui.
Este exemplo mostra combinações de 1 até 4, em terno.
Como faço para alterar as combinações para de 1 até 10 em terno, pois quando mundo o números de elementos da matriz, ele também muda a combinação, sempre subtraindo 1 do números total de elementos.
Você poderia me ajudar?
Onde determino a quantidade de Números e a quantidade de combinações, por exemplo:
Parace óbvio mas não consegui.
Este exemplo mostra combinações de 1 até 4, em terno.
Como faço para alterar as combinações para de 1 até 10 em terno, pois quando mundo o números de elementos da matriz, ele também muda a combinação, sempre subtraindo 1 do números total de elementos.
Você poderia me ajudar?
GOSTEI 0
Marconi
10/11/2003
Desculpe não responder imediatamente, mas só lí hoje.
Voce pode dimensionar a Matriz do tamanho que desejar.
Para 10 números será setlenght(M,10)
mais uma vez lembrando que o décimo elemento é M[9] e o primeiro é M[0]. Na tentativa de ler M[10] vai dar erro de endereçamento na memória.
Também não é necessário que os números que serão combinados sejam exatamente de 1 a 10. Pode-se atribuir valores diversos.
Ex. M[0]:=5;
M[1]:=17;
... e assim por diante. Eles serão combinados de três em três.
Para mudar o número de combinações para quadras, basta acrescentar uma letra no loop;
for n:=0 to lenght(M)-3 do begin
for i:=n+1 to lenght(M)-2 do begin
for j:= i+1 to lenght(M)-1 do begin
for k:=j+1 to lenght(M) do begin
memo1.lines.add(IntToStr(M[i])+´ ´+IntToStr(M[j])+IntToStr(M[k]));
end;
end;
end;
end;
No exemplo eu estou montando quadras e em vez de determinar o valor de M, e verifico o tamanho para determinar o loop.
Para deixar o número que se deseja arranjar (ternos, quadras, quinas, etc) como variáveis, fica um pouco mais complexo, mas também é possivel.
Marconi
Voce pode dimensionar a Matriz do tamanho que desejar.
Para 10 números será setlenght(M,10)
mais uma vez lembrando que o décimo elemento é M[9] e o primeiro é M[0]. Na tentativa de ler M[10] vai dar erro de endereçamento na memória.
Também não é necessário que os números que serão combinados sejam exatamente de 1 a 10. Pode-se atribuir valores diversos.
Ex. M[0]:=5;
M[1]:=17;
... e assim por diante. Eles serão combinados de três em três.
Para mudar o número de combinações para quadras, basta acrescentar uma letra no loop;
for n:=0 to lenght(M)-3 do begin
for i:=n+1 to lenght(M)-2 do begin
for j:= i+1 to lenght(M)-1 do begin
for k:=j+1 to lenght(M) do begin
memo1.lines.add(IntToStr(M[i])+´ ´+IntToStr(M[j])+IntToStr(M[k]));
end;
end;
end;
end;
No exemplo eu estou montando quadras e em vez de determinar o valor de M, e verifico o tamanho para determinar o loop.
Para deixar o número que se deseja arranjar (ternos, quadras, quinas, etc) como variáveis, fica um pouco mais complexo, mas também é possivel.
Marconi
GOSTEI 0
Marconi
10/11/2003
:oops:
Correção
No exemplo anterior mude as linhas abaixo
for n:=0 to lenght(M)-4 do begin
for i:=n+1 to lenght(M)-3 do begin
for j:= i+1 to lenght(M)-2 do begin
for k:=j+1 to lenght(M)-1 do begin
senão vai dar erro.
Marconi
Correção
No exemplo anterior mude as linhas abaixo
for n:=0 to lenght(M)-4 do begin
for i:=n+1 to lenght(M)-3 do begin
for j:= i+1 to lenght(M)-2 do begin
for k:=j+1 to lenght(M)-1 do begin
senão vai dar erro.
Marconi
GOSTEI 0
Marconi
10/11/2003
Completando
Para que o número de elementos a ser combinados possa também ser escolhido durante a execução do programa, voce precisará de outra matriz para controlar os ´loops´.
Em vez de declarar as variáveis n,i,j,k, etc. pode-se declarar uma Matriz variaveis inteiras, para controlar os loops e para que possa ser dimensionada em tempo de execução.
Marconi
Para que o número de elementos a ser combinados possa também ser escolhido durante a execução do programa, voce precisará de outra matriz para controlar os ´loops´.
Em vez de declarar as variáveis n,i,j,k, etc. pode-se declarar uma Matriz variaveis inteiras, para controlar os loops e para que possa ser dimensionada em tempo de execução.
Marconi
GOSTEI 0
Anarchybra
10/11/2003
Marconi, gostaria de agradecer sua atenção e te pedir um último favor.
Meu programa, funciona basicamente assim:
O usuário entre com a quantidade de números que ele quer fazer a combinação. Sempre em sequência e em ordem crescente e eu faço as combinações para ele.
Por enquanto, com as dicas que me deu, a quantidade de números é automática [b:56fb0486c5]´SETLENGTH(M,25);´[/b:56fb0486c5]
Como faria para esta quantidade de número ser manual, onde o usuário entraria com o números e o programa realizaria todo o processo?
Muito obrigado novamente!
Meu programa, funciona basicamente assim:
O usuário entre com a quantidade de números que ele quer fazer a combinação. Sempre em sequência e em ordem crescente e eu faço as combinações para ele.
Por enquanto, com as dicas que me deu, a quantidade de números é automática [b:56fb0486c5]´SETLENGTH(M,25);´[/b:56fb0486c5]
Como faria para esta quantidade de número ser manual, onde o usuário entraria com o números e o programa realizaria todo o processo?
Muito obrigado novamente!
GOSTEI 0
Anarchybra
10/11/2003
Eu cheguei a esta procedure....
procedure tform1.duque;
var M:Array of integer;
a1, a2, n, contM, cont:integer;
begin
listbox1.items.clear;
n:=StrToInt(edit1.text);
setlength(M,n);
for contM:=0 to n do begin
for cont:=contM+1 to n-1 do begin
M[contM]:=cont;
end;
end;
for a1:=0 to length(M)-2 do begin
for a2:=a1+1 to length(M)-1 do begin
listbox1.items.add(IntToStr(M[a1])+´-´+IntToStr(M[a2]));
end;
end;
Ele faz a quantidade certa de jogos, mas não gira o contador!
procedure tform1.duque;
var M:Array of integer;
a1, a2, n, contM, cont:integer;
begin
listbox1.items.clear;
n:=StrToInt(edit1.text);
setlength(M,n);
for contM:=0 to n do begin
for cont:=contM+1 to n-1 do begin
M[contM]:=cont;
end;
end;
for a1:=0 to length(M)-2 do begin
for a2:=a1+1 to length(M)-1 do begin
listbox1.items.add(IntToStr(M[a1])+´-´+IntToStr(M[a2]));
end;
end;
Ele faz a quantidade certa de jogos, mas não gira o contador!
GOSTEI 0
Marconi
10/11/2003
No código que voce passou, eu não entendi o que se pretende com este trecho
for contM:=0 to n do begin
for cont:=contM+1 to n-1 do begin
M[contM]:=cont;
end;
end;
pode-se perfeitamente preencher a matriz com
[b:7f664c145d]for contM:=1 to n do begin
M[contM-1]:=contM;
end;[/b:7f664c145d]
Se bem que o segredo é preenche-la com outros números, que mesmo em ordem crescente não necessitam ser sequenciais.
Marconi
for contM:=0 to n do begin
for cont:=contM+1 to n-1 do begin
M[contM]:=cont;
end;
end;
pode-se perfeitamente preencher a matriz com
[b:7f664c145d]for contM:=1 to n do begin
M[contM-1]:=contM;
end;[/b:7f664c145d]
Se bem que o segredo é preenche-la com outros números, que mesmo em ordem crescente não necessitam ser sequenciais.
Marconi
GOSTEI 0
Marconi
10/11/2003
Me esclareça o que voce pretente realmente.
Combinar [b:b75ad5cf50] n números 2 a 2 [/b:b75ad5cf50]
Combinar [b:b75ad5cf50] n números com quantidades variáveis[/b:b75ad5cf50]
Seria para Loterias, então teríamos um máximo de 10.
Marconi
Combinar [b:b75ad5cf50] n números 2 a 2 [/b:b75ad5cf50]
Combinar [b:b75ad5cf50] n números com quantidades variáveis[/b:b75ad5cf50]
Seria para Loterias, então teríamos um máximo de 10.
Marconi
GOSTEI 0
Anarchybra
10/11/2003
Amigo Marconi, muito obrigado pela atenção!
No meu caso não seria para loteria (apesar da coincidência), seria para rotinas de bingo!
Agora respondendo a sua pergunta, eu queria fazer combinações de N elementos e N variáveis. Seria arbitrario, o usuário escolheria um limite de números, 50 por exemplo e a combinação, por exemplo, combinar em terno.
Agradeço novamente sua atenção, estou chegando lá!
No meu caso não seria para loteria (apesar da coincidência), seria para rotinas de bingo!
Agora respondendo a sua pergunta, eu queria fazer combinações de N elementos e N variáveis. Seria arbitrario, o usuário escolheria um limite de números, 50 por exemplo e a combinação, por exemplo, combinar em terno.
Agradeço novamente sua atenção, estou chegando lá!
GOSTEI 0
E_gama
10/11/2003
Talvez essa não seja a solução definitiva, mas já deve dar uma luz...
Para testar a rotina abaixo, coloque no form dois TMemo´s, um TEdit e um TButton, e escreva as rotinas abaixo.
No [b:2a5ac171bd]Memo1[/b:2a5ac171bd], preencha cada linha com um numero que vc quer combinar, e no [b:2a5ac171bd]Edit1[/b:2a5ac171bd] digite a quantidade de agrupamentos (no seu exemplo, é 3 - ´terno´). Quando vc clicar no [b:2a5ac171bd]Button1[/b:2a5ac171bd], o [b:2a5ac171bd]Memo2[/b:2a5ac171bd] será preenchido com os combinações geradas...
Devido a forma com foi feito, não terá uma boa performance, mas acreditando que vc não irá utilizar uma quantidade muito grande de números, então isso não será problema.
Espero que lhe ajude...
Para testar a rotina abaixo, coloque no form dois TMemo´s, um TEdit e um TButton, e escreva as rotinas abaixo.
No [b:2a5ac171bd]Memo1[/b:2a5ac171bd], preencha cada linha com um numero que vc quer combinar, e no [b:2a5ac171bd]Edit1[/b:2a5ac171bd] digite a quantidade de agrupamentos (no seu exemplo, é 3 - ´terno´). Quando vc clicar no [b:2a5ac171bd]Button1[/b:2a5ac171bd], o [b:2a5ac171bd]Memo2[/b:2a5ac171bd] será preenchido com os combinações geradas...
Devido a forma com foi feito, não terá uma boa performance, mas acreditando que vc não irá utilizar uma quantidade muito grande de números, então isso não será problema.
Espero que lhe ajude...
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Edit1: TEdit;
Memo2: TMemo;
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
procedure GeraNumeros(Vetor: TStrings; NumAgrupamentos: Integer);
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.GeraNumeros(Vetor: TStrings; NumAgrupamentos: Integer);
var AuxLista: TStrings;
S : string;
I : Integer;
begin
AuxLista := TStringList.Create;
while Vetor.Count >= NumAgrupamentos do
begin
AuxLista.Text := Vetor.Text;
while AuxLista.Count >= NumAgrupamentos do
begin
S := ´´;
for I := 0 to (NumAgrupamentos - 1) do
S := S + AuxLista.Strings[I] + ´-´;
Memo2.Lines.Add(S);
AuxLista.Delete(NumAgrupamentos - 1);
end;
Vetor.Delete(NumAgrupamentos - 2);
end;
AuxLista.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
var Vetor1, Vetor2 : TStrings;
NumAgrupamentos: Integer;
begin
Memo2.Lines.Clear;
Vetor1 := TStringList.Create;
Vetor2 := TStringList.Create;
Vetor1.Text := Memo1.Lines.Text;
Vetor2.Text := Memo1.Lines.Text;
NumAgrupamentos := StrToInt(Edit1.Text);
while Vetor1.Count >= NumAgrupamentos do
begin
GeraNumeros(Vetor1, NumAgrupamentos);
Vetor2.Delete(0);
Vetor1.Text := Vetor2.Text;
end;
end;
end.
GOSTEI 0
E_gama
10/11/2003
Desculpe-me mas tem um bug na rotina que passei anteriormente.
Vou verificar de pois repasso a rotina correta.
Vou verificar de pois repasso a rotina correta.
GOSTEI 0
Rafael Heise
10/11/2003
Você está querendo dizer um determinado número de números e quer que a função gere pra você todas as possíveis combinações sem repetir certo?????
Então, você precisa usar um array de tamanho indefinido para guardar os números, digamos que você queira começar com 1 e terminar com 4 (1,2,3,4) ou que você queira que gera apenas com os números 1,3,5,7. Então você precisa primeiro guardar esses números. Depois você precisa fazer uma função recursiva para gerar os possíveis números.
Faça o seguinte:
Primeiro, declare uma variável do tipo TStringList no private da sua unit.
Digamos Lista: TStringList;
então você faz
e mais isso:
Agora você já tem disponível um array infinito...
agora, você coloca um TSpinEdit, e dois botões, com captions Limpar e Adicionar, e um Edit com a propriedade ReadyOnly setada para True. Não esqueça de limpara a propriedade Text do edit. Dai faça então o seguinte:
botão limpar:
e no botão adicionar você coloca:
pronto. Agora você tem como adicionar números e apagar todos os números. Agora, temos que fazer a nossa função para calcular quais os possíveis valores. Então coloque um botão com caption Possíveis valores e um memo, não esquecendo de limpar apagar o ´Memo1´ que vem na propriedade Lines. Ai você faz a função recursiva da seguinte maneira:
e então você chama a função no seu botão que vai mostrar os valores
Então, você precisa usar um array de tamanho indefinido para guardar os números, digamos que você queira começar com 1 e terminar com 4 (1,2,3,4) ou que você queira que gera apenas com os números 1,3,5,7. Então você precisa primeiro guardar esses números. Depois você precisa fazer uma função recursiva para gerar os possíveis números.
Faça o seguinte:
Primeiro, declare uma variável do tipo TStringList no private da sua unit.
Digamos Lista: TStringList;
então você faz
procedure TForm1.FormCreate(Sender: TObject); begin Lista := TStringList.Create; end;
e mais isso:
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction); begin Lista.Free; end;
Agora você já tem disponível um array infinito...
agora, você coloca um TSpinEdit, e dois botões, com captions Limpar e Adicionar, e um Edit com a propriedade ReadyOnly setada para True. Não esqueça de limpara a propriedade Text do edit. Dai faça então o seguinte:
botão limpar:
TForm1.bbClear(Sender: TObject); begin Lista.Clear; Edit1.Clear; end;
e no botão adicionar você coloca:
TForm1.bbAdd(Sender: TObject); begin Lista.Add(IntToStr(SpinEdit1.Value)); Edit1.Text := Edit1.Text + ´;´ + IntToStr(SpinEdit1.Value); end;
pronto. Agora você tem como adicionar números e apagar todos os números. Agora, temos que fazer a nossa função para calcular quais os possíveis valores. Então coloque um botão com caption Possíveis valores e um memo, não esquecendo de limpar apagar o ´Memo1´ que vem na propriedade Lines. Ai você faz a função recursiva da seguinte maneira:
procedure ShowNumber(aIndex: integer); var cont: integer; index: integer; temp: string; begin cont := 0; while cont < Lista.Count-1 do begin temp := Lista[aIndex]; index := aIndex + cont; while Length(temp) < Lista.Count do begin if index >= Lista.Count-1 then index := 0 else inc(index); if index = aIndex then continue; temp := temp + Lista[index]; end; memo1.lines.add(temp); inc(cont); end; if aIndex < Lista.Count -1 then begin Inc(aIndex); ShowNumber(aIndex); end;
e então você chama a função no seu botão que vai mostrar os valores
var index: integer; begin index := 0; memo1.Clear; ShowNumber(index); end;
GOSTEI 0
Anarchybra
10/11/2003
Muito obrigado amigos, problema resolvido!
GOSTEI 0
Anarchybra
10/11/2003
Amigo Zerneo, o que você me passou foi de muita utilidade.
Agora, sem querer abusar muito, como faço para ele colocar os números em uma certa ordem, por exemplo:
se eu escolher os números 1 3 5 7 10 combinado em terno, ele deverá mostrar:
1 3 5
1 3 7
1 3 10
1 5 7
1 5 10
1 7 10
Sempre em oerdem crescente e sem repetir combinações.
você poderia me dar um help?
Muito obrigado!
Agora, sem querer abusar muito, como faço para ele colocar os números em uma certa ordem, por exemplo:
se eu escolher os números 1 3 5 7 10 combinado em terno, ele deverá mostrar:
1 3 5
1 3 7
1 3 10
1 5 7
1 5 10
1 7 10
Sempre em oerdem crescente e sem repetir combinações.
você poderia me dar um help?
Muito obrigado!
GOSTEI 0
Rafael Heise
10/11/2003
Eu acredito que ele já faça na ordem....
não entendi o que você quis..
mas pra qualquer caso, ao invés de adicionar direto no memo, adicione numa TStringList, e antes de passar para o memo chame o procedimento Sort; da StringList. Ele vai ordenar os items da StringList e então passe a StringList para o Memo
memo.lines.AddStrings(Lista);
beleza?
não entendi o que você quis..
mas pra qualquer caso, ao invés de adicionar direto no memo, adicione numa TStringList, e antes de passar para o memo chame o procedimento Sort; da StringList. Ele vai ordenar os items da StringList e então passe a StringList para o Memo
memo.lines.AddStrings(Lista);
beleza?
GOSTEI 0
Anarchybra
10/11/2003
Zerneo,
eu entendi o que quis dizer, mas o que acontece é o seguinte:
Se, por exemplo, o usuário escolher os números 1 3 5 7 combinado em terno, gostaria que o resultado fosse:
1 3 5
1 3 7
1 5 7
mas o resultado que sua função está me retornando é:
1 3 5
1 5 7
1 7 3
3 5 7
3 7 1
3 1 5
5 7 1
5 1 3
5 1 3
7 1 3
Minhas dúvidas são: Como não deixar duplicar os resultados, exemplo:
1 7 3 = 7 1 3
Desculpe pela amolação Zerneo, mas estou tendo dificuldades e meu prazo está terminando!
Muito obrigado pela atenção!
eu entendi o que quis dizer, mas o que acontece é o seguinte:
Se, por exemplo, o usuário escolher os números 1 3 5 7 combinado em terno, gostaria que o resultado fosse:
1 3 5
1 3 7
1 5 7
mas o resultado que sua função está me retornando é:
1 3 5
1 5 7
1 7 3
3 5 7
3 7 1
3 1 5
5 7 1
5 1 3
5 1 3
7 1 3
Minhas dúvidas são: Como não deixar duplicar os resultados, exemplo:
1 7 3 = 7 1 3
Desculpe pela amolação Zerneo, mas estou tendo dificuldades e meu prazo está terminando!
Muito obrigado pela atenção!
GOSTEI 0
Rafael Heise
10/11/2003
A minha função na verdade está retornando sempre todos os possíveis numeros. Então se você informar 4 valores, ele vai te devolver todas as possíveis combinações de 4 valores.
Tem que ver como fazer do jeito que você quer...
não sei assim ... tem que parar e pensar... e agora eu estou cheio de coisas pra fazer e não vou poder parar...
me desculpe...
assim que eu puder eu te ajudo...
foi mal...
não me entenda mal, não estou negando ajuda, mas aqui no meu trabalho tenho algumas coisas pra fazer e tenho que dar prioridade pra isso.
Vou terminar minhas coisas e ver o que posso fazer pra te ajudar.. valeu
Tem que ver como fazer do jeito que você quer...
não sei assim ... tem que parar e pensar... e agora eu estou cheio de coisas pra fazer e não vou poder parar...
me desculpe...
assim que eu puder eu te ajudo...
foi mal...
não me entenda mal, não estou negando ajuda, mas aqui no meu trabalho tenho algumas coisas pra fazer e tenho que dar prioridade pra isso.
Vou terminar minhas coisas e ver o que posso fazer pra te ajudar.. valeu
GOSTEI 0
Anarchybra
10/11/2003
beleza Zerneo, agradeço.
GOSTEI 0