[ Foro de Pascal ]

pasar de este fragmento de codigo for a un while y repeat

18-Jan-2012 20:59
oscar gomez
6 Respuestas

cordial saludo profesor Nacho Cabanes, gracia por atendernos siempre con tanta amabilidad y tanta ayuda.
profesor es que queria me ayudaras a convertir un codigo que realice , y que me funciona ok, pero al intentar llevarlo a una estructura while y repeat, al ejecutarlo me hace bucle infinito y pues quisiera que me indicaras como podria hacerlo.

el fragmento es:


procedure lo_ que_sea(parametros.., numpart..)
 var
   tiempo:tiempos;
   i:integer;
   
 begin
    for i:=1 to numpart do
      begin
         if (c[i].pais=pais) then
            begin
              tiempo[i]:=calculartiempo(parametros..);
              writeln('.........');
             end;
         end;
  end;  
       

como llevo el anterior fragmento a  una estrutura while y repeat?
la condicion que debe cumplirse en cualquiera de los dos bucles mencionados es que c[i].pais= pais

en el repeat logicamente que para detener su ciclo seria, repita hasta que c[i].pais<>pais, pero el problema es que lo he intentado y en la ejecucion se desborda.

por favor no tenga en cuenta los parametros en cuenta da igual,lo que me interesa es llevar ese bloque a un bloque while y repeat.

mil gracias por su ayuda como siempre y su valioso tiempo y paciencia.





18-Jan-2012 22:20
Jose Torres

Espero que Nacho no se enoje si te respondo yo :)

Tu código quedaría así:

procedure lo_ que_sea(parametros.., numpart..)
 var
   tiempo:tiempos;
   i:integer;
 
 begin
   i  := 1;
   repeat
      if (c[i].pais=pais) then
        begin
          tiempo[i]:=calculartiempo(parametros..);
          writeln('.........');
        end;
      inc(i); // ó i := i+1
   until i > numpart;
 end;  

La diferencia fundamental entre el repeat y el for es que el repeat se ejecuta SIEMPRE al menos una vez, no importa el valor de inicio ni la condición. Saludos!


19-Jan-2012 10:28
oscar gomez

Gracias Jose por tu aporte, esta ok, el problema que tenia es que yo hacia esto, no me daba cuenta, siendo tan sencillo, jeje gracias.

procedure lo_ que_sea(parametros.., numpart..)
 var
   tiempo:tiempos;
   i:integer;
 
 begin
   i  := 1;
   repeat
     if (c[i].pais=pais) then
       begin
         tiempo[i]:=calculartiempo(parametros..);
         writeln('.........');
       end;
     inc(i); // ó i := i+1
   until (c[i].pais<>pais);
 end;
como veis , el problema estaba en el until.pero gracias a ti me di cuenta de ello gracias.


19-Jan-2012 19:16
oscar gomez

cordial saludo profesor Nacho Cabanes.
profesor queria preguntarte que tengo que corregir o hacer para que el codigo me pregunte cada vez que el pais sea distinto al que se encuentre en la estructura, por uno nuevo, y que logicamente me procese lo demas una vez introduzca un pais que si esté en la estructura:
lo he intentado de esta DOS formas pero cuando digito porejemplo:


digite un pais:italia (que no esta )
digite un nuevo pais: españa ( que si está , aun asi me sigue preguntando: digite un nuevo pais, vamos que se queda el ciclo infinito)

FORMA 1:
en el program principal tengo:
...
...
writeln('introduzca la nacionalidad de la persona: ');
 readln(c[i].pais);
  posiciones_por pais(c,numpart,pais);



procedure posiciones_por_pais(var c:carrera;numpart:integer;pais:cadena);

    var
        tiempo:tiempos;
        i:integer;

 
   begin

      i:=1;
     
      repeat
        if c[i].pais=pais then
           begin
             tiempo[i]:=calculartiempo(parametros);
              writeln('...............');
            end
              else
                  begin
                     writeln('no esta el pais');
                     writeln('digite un nuevo pais : ');
                     readln(c[i].pais)
                   end;
              inc(i);
            until (i>numpart);

    end;


****************************************************************
FORMA 2.

en el program principal tengo:
...
...
writeln('introduzca la nacionalidad de la persona: ');
 readln(c[i].pais);
  posiciones_por pais(c,numpart,pais);



procedure posiciones_por_pais(var c:carrera;numpart:integer;pais:cadena);

    var
        tiempo:tiempos;
        i:integer;

 
   begin

      i:=1;
      repeat
            repeat
               if c[i].pais=pais then
                  begin
                   tiempo[i]:=calculartiempo(parametros);
                   writeln('...............');
                 end;
               inc(i);
             until (i>numpart);

           writeln('no esta el pais');
           writeln('digite un nuevo pais : ');
           readln(c[i].pais)
         until (c[i].pais<>pais);
         
     end;


por tu ayuda mil gracias profesor.


20-Jan-2012 10:50
Nacho Cabanes (+31)

La forma de volver a pedir un dato ya existente es la que hemos comentado en el hilo "vector de numeros aleatorios con restriccion":

- Pides dentro de un "repeat-until", y, para cada nuevo valor, recorres los anteriores con "for", para asegurarte de que no se han usado con anterioridad.

Si no lo consigues, publica un fuente, lo más sencillo que puedas, pero a la vez "completo": capaz de compilar, para que podamos hacer pruebas rápidas y ayudarte con la parte que falle.


20-Jan-2012 19:12
oscar gomez

buenas tardes profesor Nacho cabanes.profesor desde el respecto que me merece Ud. perdoneme es que tu respuesta anterior a este hilo no es lo que queria pedirte en tu ayuda, seguro que me hice entender mal y te pido disculpas por ello. me refiero a que lo que me dices del vector de numeros aleatorios con restriccion, no es referente a lo que pregunto en el codigo que te inclui,pues ese hilo del vector aleatorio con retriccion ya lo solucione y tambien gracias a ti, sin embargo y permitamelo por favor a lo que me refiero en mi pregunta es respecto a lo siguiente:

en el program principal tengo:
...
...
writeln('introduzca la nacionalidad de la persona: ');
 readln(c[i].pais);

 posiciones_por pais(c,numpart,pais);
...


procedure posiciones_por_pais(var c:carrera;numpart:integer;pais:cadena);

   var
       tiempo:tiempos;
       i:integer;


   begin

     i:=1;
   
     repeat
       if c[i].pais=pais then
           begin
             tiempo[i]:=calculartiempo(parametros);
             writeln('...............');
           end
         inc(i);
      until (i>numpart);

   end;

mi pregunta profesor es con este codigo que tengo y que me va ok en el programa que estoy realizando, quiero mejorarlo en el aspecto de que me permita cuando la condicion dentro del procedimiento ( posiciones_por_pais ):
 ...

         if c[i].pais=pais then
           ....

no se cumpla, es decir que el pais que se digito por pantalla desde el programa principal ,al llegar a este if del procedimiento en mencion , me permita volver a pedir uno nuevo, sin necesidad de terminar la ajecucion, sino en ese mismo instante.porejemplo:


en pantalla me pide el pais:
porejemplo ,digito España ( al no estar) me saliera:

el pais no se encuentra, digite otro pais por favor:
y al entrar ese nuevo pais que si esta ejecute nuevamente el ciclo del repeat( para que vuelva desde el inicio a buscar con ese nuevo pais)dentro del procedimiento(posiciones_por_pais):
...
i:=1;
     repeat
       if c[i].pais=pais then
           begin
             tiempo[i]:=calculartiempo(parametros);
             writeln('...............');
           end
         inc(i);
      until (i>numpart);

......

espero haberme hecho entender y mil gracias por atender siempre nuestras dudas y poder ayudarme en indicarme que deberia anexar dentro del procedimiento para que pueda lograr mi intencion.mil gracias profesor.


22-Jan-2012 11:48
Nacho Cabanes (+31)

Entonces, si no he entendido mal, la duda sería cómo hacer que te vuelva a pedir el país si tecleas uno que no está en la lista.

Una recomendación: busca siempre la forma más legible de conseguirlo, y eso suele implicar el uso de funciones auxiliares.

Podría ser algo como

repeat
 paisEscogido := pedirUnPais;
until pertenece(paisEscogido, listaDePaisesAceptables, cantidadPaisesAceptables);
c[i].pais = paisEscogido;


Donde "pedirUnPais" sería una función que devolvería una cadena de texto, así:

function pedirUnPais: string;
var
 paisTemp: string;
begin
 writeln('introduzca la nacionalidad de la persona: ');
 readln(paisTemp);
 pedirUnPais := paisTemp;
end;




Y "pertenece" sería una función que devolvería "true" si ese país que se ha escogido pertenece a una lista, la de los países aceptables, así:


function pertenece(pais: string, lista: listaPaises, cantidadPaises: integer): boolean;
var
 encontrado: boolean;
 i: integer
begin
 encontrado := false;
 for i:= 1 to cantidadPaises
 begin
   if pais = listaPaises[i] then encontrado := true;
 end;
 pertenece := encontrado;
end;


La lógica exacta (y la sintaxis exacta incluso) dependerán de tu problema concreto, pero espero que te den ideas.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)