Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Otros entornos y lenguajes > Lazarus, FreePascal, Kylix, etc.
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 22-04-2017
Daniel2622 Daniel2622 is offline
Miembro
 
Registrado: Apr 2017
Posts: 29
Poder: 0
Daniel2622 Va por buen camino
Números impares desde 1 hasta 1000

Hola, necesito ayuda con el siguiente ejercicio:
Escribe un programa que imprima en un objeto Memo los números impares desde 1 hasta 1000.

Este es el código que he construido:

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
var c,n1,n2:Integer;
    a,b:Integer;
    i:Integer;
begin
Memo1.Lines.Clear;
Memo1.Text:='Numeros impares';
if n1then
begin
 a:=1;
 b:=1000;
 end
else
begin
  a:=1000;
  b:=1;
end;
 For i:=a to b do
begin
  c:=1;
  while c<=1000 do
begin
  Memo1.Lines.Add(
  IntToStr(n1)+'  '+IntToStr(n2)+FloatToStr(i mod c)!=0;
end;
  Memo1.Lines.Add('          ');
 end;
end;

Me dice que el operador de relación != es ilegal.

De antemano gracias por su ayuda.
Saludos.
Responder Con Cita
  #2  
Antiguo 22-04-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.410
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Para empezar, copia y pega correctamente tu código, pues ese código seguro que no te compila.
Después revisa esa línea que te da error, mezclando texto con números, al mismo tiempo que haces una comparación/validación

Y para futuras preguntas, recuerda poner títulos descriptivos al problema que tienes, y no pongas el enunciado de la tarea que te han encomendado.
¿Has leído ya nuestra guía de estilo?
Responder Con Cita
  #3  
Antiguo 22-04-2017
Daniel2622 Daniel2622 is offline
Miembro
 
Registrado: Apr 2017
Posts: 29
Poder: 0
Daniel2622 Va por buen camino
Es que así esta mi código y perdón por no hacer bien el título.
Responder Con Cita
  #4  
Antiguo 22-04-2017
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: May 2003
Ubicación: Colombia
Posts: 7.027
Poder: 23
jhonny Va camino a la fama
Voy a dejarte el siguiente código con el animo de que le tomes amor a la herramienta y no sólo se quede en que pudiste resolver la tarea, lo estoy haciendo sin Delphi a la mano sin embargo lee bien los comentarios y compara con el código que enviaste para que veas lo que estabas haciendo errado y cómo puedes mejorar tu producción de código, un abrazo:

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
var 
  i :Integer;
begin
   Memo1.Text:='Numeros impares'; //Al usar la propiedad Text reemplazas todo el texto que tenías, por eso 
                                                     //no necesitas Clear acá
   for i := 1 to 1000 do //Recorremos los números que necesitas evaluar, del 1 al 1000
   begin
      if ((i mod 2) <> 0) then //Los números divididos por 2 cuyo residuo es 0, son pares.
        Memo1.Lines.Add(IntToStr(i));
   end;
end;

Espero te sirva de ayuda y compartas con nosotros la calificación... de o de la profe .
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/

Última edición por jhonny fecha: 23-04-2017 a las 04:33:08. Razón: Es impar, no par como estaba saliendo
Responder Con Cita
  #5  
Antiguo 22-04-2017
Daniel2622 Daniel2622 is offline
Miembro
 
Registrado: Apr 2017
Posts: 29
Poder: 0
Daniel2622 Va por buen camino
Muchas gracias jhonny me fue de gran ayuda tu código, y si ya vi cuales eran mis errores.

De nuevo muchas gracias y Saludos.
Responder Con Cita
  #6  
Antiguo 23-04-2017
Avatar de roman
roman roman is offline
Moderador
 
Registrado: May 2003
Ubicación: Ciudad de México
Posts: 20.172
Poder: 10
roman Tiene un aura espectacularroman Tiene un aura espectacular
Cita:
Empezado por jhonny Ver Mensaje
Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
var 
  i :Integer;
begin
   Memo1.Text:='Numeros impares'; //Al usar la propiedad Text reemplazas todo el texto que tenías, por eso 
                                                     //no necesitas Clear acá
   for i := 1 to 1000 do //Recorremos los números que necesitas evaluar, del 1 al 1000
   begin
      if ((i mod 2) = 0) then //Los números divididos por 2 cuyo residuo es 0, son pares.
        Memo1.Lines.Add(IntToStr(i));
   end;
end;
Yo creo que podemos evitarnos el condicional:

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
var 
  i :Integer;
begin
   Memo1.Text:='Numeros impares';
                                                    
   for i := 0 to 499 do
   begin
        Memo1.Lines.Add(IntToStr(2*i + 1));
   end;
end;


LineComment Saludos

Última edición por roman fecha: 23-04-2017 a las 00:25:44.
Responder Con Cita
  #7  
Antiguo 23-04-2017
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: May 2003
Ubicación: Colombia
Posts: 7.027
Poder: 23
jhonny Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Yo creo que podemos evitarnos el condicional:

Código Delphi [-]
procedure TForm1.BitBtn1Click(Sender: TObject);
var 
  i :Integer;
begin
   Memo1.Text:='Numeros impares';
                                                    
   for i := 0 to 499 do
   begin
        Memo1.Lines.Add(IntToStr(2*i + 1));
   end;
end;


LineComment Saludos

¡Estupendo!, al ver que has reducido el tiempo de ejecución a la mitad usando ingenio puro. Sólo resta mejorar aún más la velocidad de ejecución, aprovechando las nuevas herramientas, sin ser algo perfecto porque faltaría el tema del ordenamiento (aunque en el ejercicio no piden que sea ordenado)... así:

Agregando al uses las unidades System.Threading y System.SyncObjs...

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
  vCS: TCriticalSection;
  vStringList: TStringList;
begin
  vStringList := TStringList.Create;
  try
    vCS := TCriticalSection.Create;

    TParallel.&For(0, 499,
      procedure(pI: Integer)
      begin
        vCS.Acquire;
        vStringList.Add((2 * pI + 1).ToString);
        vCS.Release;
      end);

    Memo1.Text := 'Numeros impares';
    Memo1.Lines.AddStrings(vStringList);
  finally
    vCS.DisposeOf;
    vStringList.DisposeOf;
  end;
end;

Ejecutando este mismo ejercicio hasta 10000 en lugar de 1000, en mi maquina con el método anterior se demoró 3150 milisegundos en promedio, sin embargo con el segundo método 295 milisegundos en promedio.

O cuando lo subí a 100000 el promedio con el ejercicio anterior fue de 33843 milisegundos, mientras que con el segundo ha sido de 2900 milisegundos.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/

Última edición por jhonny fecha: 23-04-2017 a las 06:56:43.
Responder Con Cita
  #8  
Antiguo 23-04-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.410
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
¿Eso es de los últimos delphi? ¿qué hace, aprovechar el multiproceso?
Responder Con Cita
  #9  
Antiguo 23-04-2017
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: May 2003
Ubicación: Colombia
Posts: 7.027
Poder: 23
jhonny Va camino a la fama
Cita:
Empezado por Casimiro Notevi Ver Mensaje
¿Eso es de los últimos delphi? ¿qué hace, aprovechar el multiproceso?
Así es , tengo entendido que Lazarus también tiene TParallel pero recibe es un puntero a un procedimiento... aunque no lo he probado.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #10  
Antiguo 23-04-2017
Avatar de escafandra
[escafandra] escafandra is offline
Miembro Premium
 
Registrado: Nov 2007
Posts: 1.930
Poder: 13
escafandra Va camino a la famaescafandra Va camino a la fama
El código puede escribirse de muchas formas pero lo que lo retrasa el la línea Memo1.Lines.Add(
Código Delphi [-]
// Similar al de roman con multiplicación binaria
var
  i :Integer;
begin
  Memo1.Text:='Numeros impares';

 for i := 0 to 499 do
   Memo1.Lines.Add(IntToStr((i shl 1) + 1));
end;

Código Delphi [-]
var
  i: integer;
begin
  i:= 1;
  Memo1.Text:='Numeros impares';
  repeat
    Memo1.Lines.Add(IntToStr(i));
    inc(i,2);
  until i > 999;
end;

Si hacemos que el memo se escriba por mensajes, cualquiera de las formas se ejecuta en menos de 10 milisegundos:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
var
  i: integer;
begin
  i:= 1;
  Memo1.Text:='Numeros impares';
  repeat
    //Memo1.Lines.Add(IntToStr(i));
    PostMessage(Handle, WM_USER, i, 0);
    inc(i,2);
  until i > 999;
end;

procedure TForm1.OnMsg(var Msg: TMessage);
begin
  Memo1.Lines.Add(IntToStr(Msg.WParam));
end;

Los bucles terminarán en escasos milisegundos aunque el Memo tardará en llenarse de forma ordenada lo que tarde Windows en tramitar la cola de mensajes.


Saludos.
Responder Con Cita
  #11  
Antiguo 23-04-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.410
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por escafandra Ver Mensaje
El código puede escribirse de muchas formas pero lo que lo retrasa el la línea Memo1.Lines.Add(
Se puede almacenar en memoria y luego, al terminar, asignarlo al memo. Así será incluso más rápido.
Responder Con Cita
  #12  
Antiguo 23-04-2017
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: Dec 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.083
Poder: 29
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola.

Si, el método Add es muy lento; yo he obtenido buenos resultados operando sobre una variable de tipo string y asignándola luego a la propiedad Text.
Código Delphi [-]
...
begin
   s := '';
  for i := 0 to 499 do
    s := s + IntToStr(2 * i + 1) + CRLF; // (#13#10)
  Memo1.Text := s; 
end;
Resultados para 1000 números usando la propuesta de roman en todos los casos:
Código:
Concatenando : 203 µs.
Mensaje      : 261 µs.
Método Add   : 3320579 µs.
Como se vé, ya sea concatenando o usando la cola de mensajes como sugirió escafandra la diferencia es astronómica. Lo que no pude probar son las nuevas herramientas que menciona jhonny, pero supongo que mejorarán mas los tiempos.

Saludos

Edito: Mas o menos como lo que dijo Casimiro mientras componía este
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....

Última edición por ecfisa fecha: 23-04-2017 a las 22:32:48.
Responder Con Cita
  #13  
Antiguo 24-04-2017
Avatar de Casimiro Notevi
Casimiro Notevi Casimiro Notevi is offline
Moderador
 
Registrado: Sep 2004
Ubicación: En algún lugar.
Posts: 28.410
Poder: 10
Casimiro Notevi Tiene un aura espectacularCasimiro Notevi Tiene un aura espectacular
Cita:
Empezado por ecfisa Ver Mensaje
Si, el método Add es muy lento; yo he obtenido buenos resultados operando sobre una variable de tipo string y asignándola luego a la propiedad Text.
Cierto, el manejo de cadenas de texto suele ser siempre lo más lento de todo.
Responder Con Cita
  #14  
Antiguo 24-04-2017
Avatar de roman
roman roman is offline
Moderador
 
Registrado: May 2003
Ubicación: Ciudad de México
Posts: 20.172
Poder: 10
roman Tiene un aura espectacularroman Tiene un aura espectacular
Bueno, pero antes de agregar líneas por PostMessage o concatenar y pegar, ¿han intentado un BeginUpdate - EndUpdate?

LineComment Saludos
Responder Con Cita
  #15  
Antiguo 24-04-2017
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: May 2003
Ubicación: Colombia
Posts: 7.027
Poder: 23
jhonny Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Bueno, pero antes de agregar líneas por PostMessage o concatenar y pegar, ¿han intentado un BeginUpdate - EndUpdate?

LineComment Saludos
Ahhh caramba, ¿VCL también tiene estos métodos?... porque los he usado es en FMX.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #16  
Antiguo 24-04-2017
Avatar de roman
roman roman is offline
Moderador
 
Registrado: May 2003
Ubicación: Ciudad de México
Posts: 20.172
Poder: 10
roman Tiene un aura espectacularroman Tiene un aura espectacular
Sí, claro. Ahí han estado por siempre

LineComment Saludos
Responder Con Cita
  #17  
Antiguo 24-04-2017
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: May 2003
Ubicación: Colombia
Posts: 7.027
Poder: 23
jhonny Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Sí, claro. Ahí han estado por siempre

LineComment Saludos
Roman, definitivamente, sos el maestro (bueno, eso siempre se ha sabido), acabo de probarlo y funciona a las mil maravillas... no encontraba el método porque estaba buscando en el control, como si se tratara de FMX... sin embargo sí que ha funcionado a las mil maravillas al utilizarlo en el TStrings que es a donde ha pertenecido.

Gracias hombre.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #18  
Antiguo 24-04-2017
Avatar de roman
roman roman is offline
Moderador
 
Registrado: May 2003
Ubicación: Ciudad de México
Posts: 20.172
Poder: 10
roman Tiene un aura espectacularroman Tiene un aura espectacular
Oye jhonny, ¿podrías explicar un poco eso del TParallel? Bueno, es que ni la sintaxis entiendo ¿qué hace un & ahí?

LineComment Saludos
Responder Con Cita
  #19  
Antiguo 24-04-2017
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: May 2003
Ubicación: Colombia
Posts: 7.027
Poder: 23
jhonny Va camino a la fama
Cita:
Empezado por roman Ver Mensaje
Oye jhonny, ¿podrías explicar un poco eso del TParallel? Bueno, es que ni la sintaxis entiendo ¿qué hace un & ahí?

LineComment Saludos
Hombre, claro, espero ser de ayuda, ahí va:

TParallel es una clase que tiene varios métodos cuyo objetivo es ejecutar tareas (como su nombre lo indica) en paralelo, TParallel te hace más fácil el uso de los TTask (Que es como la nueva clase para manejo de hilos, si no que usa el TMonitor para la administración de la ejecución de hilos), es especial para aquellos casos de uso cotidiano, como lo es en este caso un mero for de toda la vida.

TParallel tiene otro métodos a parte del for, el cual es Join... que también sirve para ejecutar varias tareas al tiempo... pero vamos a la explicación de la sintaxis y del asunto del &.

1) El &, este es un comodín que agregaron en Delphi (No recuerdo desde cual versión realmente), el cual sirve para que puedas ponerle como nombre a tus métodos aquellas palabras que siempre han sido reservadas... para el caso que vemos, la palabra For... entonces, podrías por ejemplo ponerle a un método de una clase tuya, el nombre While, anteponiendo simplemente &While... incluso podrías llamar tu método While usando TTuClase.While, sin el &... sin embargo soy de los que prefiere ponerle el & para evitar posibles "situaciones".

2) La sintaxis de TParallel:

Código Delphi [-]
procedure TForm1.Button2Click(Sender: TObject);
var
  vCS: TCriticalSection;
  vStringList: TStringList;
begin
  vStringList := TStringList.Create;
  try
    vCS := TCriticalSection.Create;

    TParallel.&For(0, 499,
      procedure(pI: Integer)
      begin
        vCS.Acquire;
        vStringList.Add((2 * pI + 1).ToString);
        vCS.Release;
      end);

    Memo1.Text := 'Numeros impares';
    Memo1.Lines.AddStrings(vStringList);
  finally
    vCS.DisposeOf;
    vStringList.DisposeOf;
  end;
end;

  • TParallel tiene "dos" métodos de clase principales (un método de clase nos permite hacer llamado al método sin necesidad de instanciar la clase, por eso está declarado como class function &For( ) dentro de la clase) y puedo llamarlo directamente con TParallel.&For.
  • TParallel tiene 2 métodos de clase los cuales son For y Join... ambos tienen bastantes sobre cargas, en el For una de sus sobrecargas es aquella que usé para este caso, en ella pasas el primer valor del recorrido, el último y un método anónimo... en el caso del método anónimo (Que es el que está entre el procedure...begin...end)... éste devuelve el número que está "recorriendo" (lo pongo entre comillas porque este "recorrido" es en paralelo), este número lo capturas en una variable (en el caso del ejemplo me inventé el nombre pI que es el que contendrá el valor de dicho número... esta variable puede tener el nombre que quieras mientras respetes la convención del nombre de una variable) y este método anónimo es el que ejecutará todo aquello que quieres que se ejecute en paralelo.
  • El TCriticalSection es en sí la "señal de semaforización" para que se ejecute lo que está entre el Acquire y el Release, cuando el proceso anterior haya terminado... es el TCriticalSection que siempre se ha usado con TThread.

Es muy curioso que preguntes por esto, porque tengo hace rato en el tintero un artículo donde quiero explicar este tema, aunque nunca encuentro es ¿Por dónde comenzar?, puesto que hay que explicar primero el uso de métodos anónimos, los class methods o bueno... tal vez al revés... me ayudaría mucho tu retroalimentación acerca de si se entendió más o menos lo que trato de explicar y lo que ha quedado en el completo aire para complementar y explicarlo mejor.
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/

Última edición por jhonny fecha: 24-04-2017 a las 19:50:11.
Responder Con Cita
  #20  
Antiguo 24-04-2017
Avatar de ecfisa
ecfisa ecfisa is offline
Moderador
 
Registrado: Dec 2005
Ubicación: Tres Arroyos, Argentina
Posts: 10.083
Poder: 29
ecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to beholdecfisa is a splendid one to behold
Hola roman.
Cita:
Empezado por roman Ver Mensaje
Bueno, pero antes de agregar líneas por PostMessage o concatenar y pegar, ¿han intentado un BeginUpdate - EndUpdate?

LineComment Saludos
Olvidé incluirlos en las pruebas , tal vez por que recordaba que aunque mejoraba el tiempo, no lo hacía un rival de la concatenación.
Código:
Concatenando  :     203 µs.
Mensaje       :     261 µs.
Begin/Update  :  858024 µs.
Método Add    : 3320579 µs.
Saludos
__________________
Daniel Didriksen

Guía de estilo - Uso de las etiquetas - La otra guía de estilo ....
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
Copiar números impares de un listbox a otro ale4132 Varios 5 17-12-2012 19:33:10
Consulta Desde->Hasta Luis M. Firebird e Interbase 6 30-07-2008 19:40:34
1000 Mil M 0011 1110 1000 3e8 sakuragi La Taberna 29 05-03-2008 18:28:56
Poner puntos a los números mayores de 999 y hasta 1M Pedro-Juan Trucos 2 26-12-2007 19:13:08
Factorial hasta 1000 Cheswar Varios 29 21-09-2007 20:43:27


La franja horaria es GMT +2. Ahora son las 19:36:35.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi