PDA

Ver la Versión Completa : Problema recorriendo ListView


danielmj
13-05-2013, 14:50:26
Hola, tengo un problema con un Tlistview, estoy tonteando con el tipico programa de los numeros de la loteria, es decir, el listView tiene seis columnas y (por el momento) 100 filas, en cada celda se almacena un numero aleatorio del 1 al 49, hasta ahí todo bien. El problema viene cuando quiero recorrer todo el listView para buscar los 6 numeros que mas se repiten de entre todas las celdas.
El codigo ahora mismo lo tengo escrito para buscar un solo numero, en teoria el que mas se repite de entre todos.

procedure TForm1.Button2Click(Sender: TObject);
var
elemento: tlistitem;
begin
numtot:= 0;
for y := 0 to listView1.Items.Count -1 do
for z := 0 to 49 - 1 do
begin

elemento := listView1.FindCaption(0,(IntToStr(z)),true,true,true); //.Findcaption(0,18,true,true,false) then
if (elemento <> nil) and (z = 10) then
inc(numtot);
label7.Caption:= IntToStr(numtot);
end;

end;

Cuando se ejecuta este trozo del codigo, el resultado siempre es 0
¿donde está el error? ¿no debería ir aumentando el valor de 'numtot' según se vaya repitiendo el número 18 y mostrarlo luego en el label7?
¿Existe otra forma de encontrar los numeros que mas se repiten de entre todas las celdas?

Otro problema que tengo y esto si es un error, es que si ejecuto la aplicacion el pc se cuelga, pero si la ejecuto con delphi abierto de fondo, NO se cuelga. ¿? abajo pongo el texto de la ventana de error que devuelve windows. El numero de veces que se realizan los cálculos aletarios es 21.600.000 veces, por que recorre dos FOR, uno que va hasta 100.000 y otro que va hasta 216 (que es multiplo de 6 (6*6*6)) igual el numero es muy elevado pero deberia fallar aunque delphi este abierto y no solo cuando ejecuto la aplicación con delphi cerrado.

Firma con problemas:
Nombre del evento de problema: AppHangB1
Nombre de aplicación: aleatorios.exe
Versión de la aplicación: 0.0.0.0
Marca de tiempo de la aplicación: 5190d797
Firma de bloqueo: 0c4f
Tipo de bloqueo: 0
Versión del sistema operativo: 6.1.7600.2.0.0.256.48
Id. de configuración regional: 3082
Firma adicional de bloqueo 1: 0c4f0997d399d366524a814f7832f13b
Firma adicional de bloqueo 2: 57cc
Firma adicional de bloqueo 3: 57ccfdb22112c570b5d960f240e02003
Firma adicional de bloqueo 4: 0c4f
Firma adicional de bloqueo 5: 0c4f0997d399d366524a814f7832f13b
Firma adicional de bloqueo 6: 57cc
Firma adicional de bloqueo 7: 57ccfdb22112c570b5d960f240e02003Gracias y saludos.

Casimiro Notevi
13-05-2013, 16:02:41
Recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias :)

danielmj
13-05-2013, 16:42:08
hola casimiro, lo hice creeme, pero cuando le doy a previsualizar mensaje, desaparece y lo pone como texto normal y corriente, siempre me pasa lo mismo cuando he escrito en este foro, y ya aburrido (te soy sincero), opte por ponerlo asi como aparece en el mensaje.

un saludo.

Casimiro Notevi
13-05-2013, 16:47:51
La solución es fácil y simple: "no le des primero a "previsualizar" :)
Verás que sale bien. Y si acaso hay algo mal, no te preocupes, porque podrás editarlo sin problema.
Es un pequeño fallo que tiene esa opción.

danielmj
13-05-2013, 16:59:21
ah, vale gracias por el aviso. saludos.

Al González
13-05-2013, 17:01:09
A ver, esto es una prueba.
Segunda línea con sangrado de dos espacios.
Tercera línea con sangrado de cuatro espacios.
Acá no hubo ningún problema cuando presioné el botón de vista previa (Firefox 20.0.1). :confused:

cloayza
13-05-2013, 19:28:55
Prueba este código a ver si te sirve...

Crea un nuevo proyecto

procedure TForm3.BitBtn1Click(Sender: TObject);
var
Item, Item2:TlistItem;
Col:TListColumn;
i, j, Value, count:Integer;
begin
Randomize;

Col:=ListView1.Columns.Add;
Col.Caption:='Número';
Col:=ListView1.Columns.Add;
Col.Caption:='Frecuencia';

Col:=ListView2.Columns.Add;
Col.Caption:='Fila';

Col:=ListView2.Columns.Add;
Col.Caption:='Col 1';

Col:=ListView2.Columns.Add;
Col.Caption:='Col 2';

Col:=ListView2.Columns.Add;
Col.Caption:='Col 3';

Col:=ListView2.Columns.Add;
Col.Caption:='Col 4';

Col:=ListView2.Columns.Add;
Col.Caption:='Col 5';

Col:=ListView2.Columns.Add;
Col.Caption:='Col 6';

ListView1.ViewStyle:=vsReport;
ListView2.ViewStyle:=vsReport;

ListView1.Items.Clear; //Frecuencias de aparición del número en la tabla...
ListView2.Items.Clear; //Tabla con números aleatorios...

{Completado de Tabla de Números para contar la frecuencia...}
for i:=0 to 49 do
begin
Item2:=ListView1.Items.Add;
Item2.Caption:=IntToStr(i);
Item2.SubItems.Add('0');
end;

//Completado de Tabla con números aleatorios.
for i:=1 to 100 do
begin
Item:=ListView2.Items.Add;

Item.Caption:=IntToStr(i);

for j := 0 to 5 do
begin
Value:=Random(49);
Item.SubItems.Add(IntToStr(Value));

//Busqueda del número aleatorio generado en tabla de Frecuencias...
Item2:=ListView1.FindCaption(0,IntToStr(Value),false,True,true);
if Item2<>nil then
begin
//Incrementa la frecuencia del número aleatorio generado...
TryStrToInt(Item2.SubItems[0],Count);
Inc(Count);
Item2.SubItems[0]:=IntToStr(Count);
end;
end;

end;
end;


Saludos cordiales...

Casimiro Notevi
13-05-2013, 20:09:02
Código Delphi [-] (http://www.clubdelphi.com/foros/#)A ver, esto es una prueba. Segunda línea con sangrado de dos espacios. Tercera línea con sangrado de cuatro espacios.

Acá no hubo ningún problema cuando presioné el botón de vista previa (Firefox 20.0.1). :confused:

Es cuando le das a "vista previa" antes de nada, antes de guardar incluso.

je, je... me he citado a mí mismo

danielmj
13-05-2013, 21:31:32
Hola, gracias por la ayuda, estoy intentando implementar mi programa con este codigo por que ya tengo echa la parte que genera los numeros aleatorios y por tema de diseño y demas, no quisiera modificarlo, asi en que en vez de copiar y pegar miro el codigo y me rompo un poco mas la cabeza, pero me esta costando un poco, ademas tengo dos label, en uno me dira los 6 numeros que mas se repiten de entre todo el listado y en otro label, mostrare cual seria la combinación una vez se tengan los 6 numeros.

A ver si lo consigo, saludos y gracias.

nlsgarcia
14-05-2013, 04:51:46
danielmj,


...tengo un problema con un Tlistview...seis columnas...100 filas...cada celda almacena un numero aleatorio del 1 al 49...
...El problema...buscar los 6 numeros que mas se repiten de entre todas las celdas...


Revisa este código:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ComCtrls;

type
TForm1 = class(TForm)
ListView1: TListView;
Button1: TButton;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TModa = record
Number : Integer;
Count : Integer;
end;

const
Secuencia : Array[0..5] of String = ('primero','segundo', 'tercero', 'cuarto', 'quinto', 'sexto');
Max = 50; // Número máximo de elementos a generar aleatoriamente
Rows = 100; // Número máximo de lineas del control TListview

var
Form1: TForm1;

implementation

{$R *.dfm}

// Genera números aleatorios de 0 a Max-1
procedure TForm1.Button1Click(Sender: TObject);
var
i : Integer;
begin
Randomize;
ListView1.Clear;
for i := 1 to Rows do
begin
with ListView1.Items.Add do
begin
SubItems.Add(IntToStr(Random(Max)));
SubItems.Add(IntToStr(Random(Max)));
SubItems.Add(IntToStr(Random(Max)));
SubItems.Add(IntToStr(Random(Max)));
SubItems.Add(IntToStr(Random(Max)));
SubItems.Add(IntToStr(Random(Max)));
end;
end;
ListView1.Items.Count
end;

// Muestra los seis primeros números repetidos de una secuencia aleatoria
procedure TForm1.Button2Click(Sender: TObject);
var
i, j, p : Integer;
ModaCount : Array[0..Max] of Integer;
AModa : Array[0..5] of TModa;
b : Boolean;

begin

// Cuenta cuantas ocurrencia hay de un número
// la posición del arreglo corresponde al número generado aleatoriamente
// El valor del arreglo corresponde a la cantidad de ocurrencias encontradas para ese número
FillChar(ModaCount,Sizeof(ModaCount),0);
for i := 0 to ListView1.Items.Count - 1 do
begin
for j := 0 to ListView1.Items.Item[i].SubItems.Count - 1 do
begin
p := StrToInt(ListView1.Items.Item[i].SubItems.Strings[j]);
ModaCount[p] := ModaCount[p] + 1;
end;
end;

// Genera un arreglo con los 6 primeros números en orden de repetición
FillChar(AModa,Sizeof(AModa),-1);
for i := Low(AModa) to High(AModa) do
for j := Low(ModaCount) to High(ModaCount) do
begin
if AModa[i].Count < ModaCount[j] then
begin

for p := 0 to 5 do
if (AModa[p].Number = j) then
b := True;

if not b then
begin
AModa[i].Number := j;
AModa[i].Count := ModaCount[j];
end;

b := False;

end;
end;

// Muestra los primeros números repetidos en secuencia hasta un máximo de 6
for i:= 0 to 5 do
begin
if (AModa[i].Count <> 0) then
ShowMessage(Format('El %s número es %d con %d ocurrencias',[Secuencia[i],AModa[i].Number,AModa[i].Count]));
end;

end;

end.

El código anterior genera números aleatorios entre 0 y 49 en un control TListView de 100 filas. Variando los valores de las constantes Max y Rows se puede analizar la salida del código de forma más manejable.

El ejemplo esta disponible en el link: http://terawiki.clubdelphi.com/Delphi/Ejemplos/Varios/?download=Frequency_Random_Numbers.rar

Espero sea útil :)

Nelson.

nlsgarcia
14-05-2013, 05:31:29
Casimiro Notevi,


...Recuerda poner los tags al código fuente...



...cuando le doy a previsualizar mensaje, desaparece y lo pone como texto normal y corriente...



...solución..."no le des primero a "previsualizar"...


Un procedimiento para poder pre visualizar y enviar el código fuente con sus correspondientes Tags es el siguiente:

1- Colocar el código fuente a enviar con sus correspondientes Tags y texto asociados y pulsar Vista Previa de Mensaje.

2- Si hay errores pulsar el Botón de Página Previa en el Navegador y corregir el error, nuevamente pulsar Vista Previa de Mensaje y repetir el paso 1 y 2 tantas veces se requiera.

3- Cuando la información a enviar este debidamente formateada y verificada en la opción de Vista Previa de Mensaje no utilizar el botón de Enviar Respuesta, en su defecto pulsar el Botón de Página Previa en el Navegador y desde esa página pulsar Enviar Respuesta con lo cual el código fuente quedara debidamente formateado.

Espero sea útil :)

Nelson.

Casimiro Notevi
14-05-2013, 10:33:07
Buena idea ^\||/

danielmj
14-05-2013, 19:08:11
Lo tendre en cuenta para futuros post jeje. gracias.

En cuanto al codigo nlsgarcía, sencillamente perfecto, es lo que buscaba, de todos modos, voy a ver como hago para que envez de usar un msg muestre los 6 numeros en etiquetas a modo de resumen, sin tener que pulsar el boton 5 veces.

saludos y gracias!

ecfisa
14-05-2013, 21:21:19
danielmj,



Revisa este código:

...

El ejemplo esta disponible en el link: http://terawiki.clubdelphi.com/Delphi/Ejemplos/Varios/?download=Frequency_Random_Numbers.rar

Espero sea útil :)

Nelson.

Muy buen ejemplo Nelson. ^\||/

Saludos. :)

ecfisa
14-05-2013, 21:33:04
...
de todos modos, voy a ver como hago para que envez de usar un msg muestre los 6 numeros en etiquetas a modo de resumen, sin tener que pulsar el boton 5 veces.

Hola.

Bastaría con agregar un TListBox o TMemo a tu form y reemplazar en el código de nlsgarcia la palabra ShowMessage por el nombre de tu ListBox o Memo.

Saludos. :)

Edito: Me faltó especificar: "Usando sus métodos Items.Add y Lines.Add respectivamente..."

danielmj
15-05-2013, 00:24:38
Hola ecfisa, perfecto!! juassssss muchas gracias a todos, ahora solo falta que la combinacion generada se la premiada jaja

Un saludo y gracias!