Fórum Gerar números - um pouco confuso! #193945
10/11/2003
0
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
Curtir tópico
+ 0Posts
10/11/2003
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
10/11/2003
Anarchybra
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
11/11/2003
Anarchybra
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
14/11/2003
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
14/11/2003
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
14/11/2003
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
18/11/2003
Anarchybra
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
18/11/2003
Anarchybra
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
21/11/2003
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
21/11/2003
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
21/11/2003
Anarchybra
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
21/11/2003
E_gama
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
21/11/2003
E_gama
Vou verificar de pois repasso a rotina correta.
Gostei + 0
21/11/2003
Rafael Heise
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
24/11/2003
Anarchybra
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)